使用ViewModel上的异步方法,caliburn.micro会做正确的事吗?

时间:2013-03-14 18:28:43

标签: wpf async-await caliburn.micro

正如其他地方所提到的,新的.NET async / await模型通过像病毒这样的软件层传播。最近的异步更改已经冒充我的视图模型,我想知道它是否是从public void DoStuff()public async Task DoStuff()的安全更改声明?

谢谢!

4 个答案:

答案 0 :(得分:17)

Caliburn.Micro中对异步编程模型的支持现在相当不错。

你可以做的事情很少:

  • 在Action方法中使用async / await 。要小心,因为动作方法在技术上是事件处理程序,所以你应该async void而不是async Task
  • 屏幕事件的异步事件处理程序,例如Activated,ViewLoaded等。
  • 屏幕方法的异步覆盖:OnInitialize,OnActivate,...您可以覆盖protected override async void OnInitialize(){},然后在内部等待其他任务。
  • 将协同程序转换为任务。使用ExecuteAsync()扩展方法。协程在某些情况下仍然具有一些优势,例如执行上下文。
  • IHandleWithTask<TMessage> - 非常方便......

a blog post desribing some use cases代码片段很少。一个GitHub repository with sample project我曾经在Caliburn玩过async / await。

答案 1 :(得分:2)

答案是“是”,从Caliburn.Micro 1.5开始。

请参阅release announcement

答案 2 :(得分:1)

Marco Amendola,Caliburn.Micro项目的项目经理撰写了一篇文章,其标题为:Coroutines are dead. Long live Coroutines.,由于async / wait编程模型的出现,他以这种方式命名,如果你读过这篇文章,你会看到异步/等待带来了Coroutines过去做过的事情,所以我假设你可以安全地使用它们之前你曾经使用过Coroutines。我建议你阅读这篇文章。

答案 3 :(得分:0)

这很安全,但是会破坏您现有的全局异常处理。进行重构之后,我再也看不到任何错误对话,为了解决此问题,我不得不订阅Coroutine.Completed事件:

Coroutine.Completed += (s, a) =>
{
    //Do something here ...
};

您可以在您的App.xaml.cs文件中进行操作。

我的代码中有关如何处理应用程序中所有可能出现的错误的示例:

protected override void OnStartup(StartupEventArgs e)
{
    SetupExceptionHandlers();
    base.OnStartup(e);
}

private void SetupExceptionHandlers()
{
    AppDomain.CurrentDomain.UnhandledException += (s, a) =>
    {
        HandleException((Exception)a.ExceptionObject, "AppDomain.CurrentDomain.UnhandledException");
    };

    Current.DispatcherUnhandledException += (s, a) =>
    {
        HandleException(a.Exception, "Application.Current.DispatcherUnhandledException");
        a.Handled = true;
    };

    TaskScheduler.UnobservedTaskException += (s, a) =>
    {
        HandleException(a.Exception, "TaskScheduler.UnobservedTaskException");
        a.SetObserved();
    };

    Coroutine.Completed += (s, a) =>
    {
        if (a.Error != null)
        {
            HandleException(a.Error, "Coroutine.Completed");
        }
    };
}

private void HandleException(Exception exception, string source)
{
    logger.Error(exception, "Unhandled exception occured (Source: {0})", source);

    var msg = new ShowErrorDialogEvent(exception, exception.GetBaseException().Message);
    eventAggregator.PublishOnUIThread(msg);
}

如果您想知道,在调用logger之前,先从eventAggregator方法中的bootstrapper类实例化OnStartupDisplayRootViewFor变量。