C#/ MonoTouch:如何在创建/显示ViewController时调用异步方法

时间:2013-08-16 00:32:39

标签: c# xamarin.ios xamarin async-await

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既不是异步方法也不是事件处理程序。

当视图控制器加载(或出现,等等)时启动后台任务的“替代”方法是什么?

3 个答案:

答案 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);
    );
}