Xamarin released支持async
/ await
,它真正简化了移动平台中响应式用户界面的开发。我想利用它,并从现在开始使用async / await东西来提高代码的编程水平。
但是,由于我对C#相对较新,并且在我无法在我的代码中找到'hooks'之前没有使用async
/ await
我可以调用{{1 }} 方法。我知道事件处理程序是典型的地方(IoC发生的地方),但想象一下以下情况:
我想在加载ViewController时启动后台任务 (而不是按下按钮时)。
async
显然我无法等待async Task PerformMyTaskAsync ()
{
// ...
await ... // another async API
// ...
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// .. initialize UI
await PerformMyTaskAsync ();
}
中的PerformMyTaskAsync
因为ViewDidLoad
既不是异步方法也不是事件处理程序。
当视图控制器加载(或出现,等等)时启动后台任务的“替代”方法是什么?
答案 0 :(得分:18)
最新的Xamarin Stable Channel版本支持ViewController生命周期方法的Async / Await重载。尝试:
public async override void ViewDidLoad()
答案 1 :(得分:0)
不确定这是否是“最佳”方法,但您是否尝试从ViewDidLoad()中触发事件,然后在该事件的处理程序中启动您的异步代码?
答案 2 :(得分:0)
因此,从事件中在UI线程上运行一些异步操作,如下所示:
Blah.OnEvent += onEvent;
protected async void onEvent(object sender, EventArgs ev)
{
...
}
void
不是错字-不幸的是,它是Xamarin针对异步UI事件所遵循的反模式。
在某些有效的情况下,您需要运行使UI等待的异步方法。例如,通过单击按钮调用Navigation.PushAsync()
。但是,您特别要求进行后台任务,这意味着可能需要一段时间。为此,您不想让UI等待。您应该启动任务并立即返回。为此,您只需使用与在任何C#TPL应用程序中使用的相同的后台任务代码:
public static void RunBg(Func<Task> fn)
{
Task.Run(fn).ConfigureAwait(false);
// Uncomment to roll up exceptions
//.GetAwaiter().GetResult();
}
public static void RunBgLong(Func<Task> fn)
{
Task.Factory.StartNew(fn, TaskCreationOptions.LongRunning).ConfigureAwait(false);
// Uncomment to roll up exceptions
//.GetAwaiter().GetResult();
}
我之所以提供这两者,是因为TPL的创造者竭尽全力在引擎盖下提供了这两者。在其他问题中,最好使用2的含义,尽管我认为“长”的区别是毫秒数。
因此,您将像这样开始任务
public override void ViewDidLoad()
{
base.ViewDidLoad();
TaskHelper.RunBg(async () => {
await someBgAsyncMethodGoesHere(arg1, arg2);
);
}