Will caliburn.micro do the right thing with async method on ViewModel?

核能气质少年 提交于 2019-12-04 09:55:05

问题


As mentioned elsewhere, the new .NET async/await model propagates through layers of software like a virus. A recent async change has now bubbled up to my view model, and I am wondering if it is safe change declaration from public void DoStuff() to public async Task DoStuff() ?

Thanks!


回答1:


The support of asynchronous programming model in Caliburn.Micro is pretty good now.

Few things you can do:

  • Use async/await in Action method. Be careful, as action methods are technically event handlers, you shoud do async void rather than async Task.
  • Asynchronous event handlers for Screen's events, like Activated, ViewLoaded and other.
  • Asynchronous overrides for Screen's methods: OnInitialize, OnActivate, ... You can override then as protected override async void OnInitialize(){} and inside you can await another task.
  • Convert Coroutines to Tasks. Use ExecuteAsync() extension method. Coroutines still have some advantages in some scenarios, like execution context.
  • IHandleWithTask<TMessage> - pretty handy...

There's a blog post desribing some use cases with few code snippets. And a GitHub repository with sample project I've used to play with async/await in Caliburn.




回答2:


The answer is 'yes', starting with Caliburn.Micro 1.5.

See release announcement.




回答3:


Marco Amendola, a project manager in the Caliburn.Micro project wrote an article that has this title: Coroutines are dead. Long live Coroutines. and he titled it this way because of the emergence of the async/wait programming model and if you read the article you will see that async/wait bring to life what Coroutines did in the past so i assume you could use them safely where you have used Coroutines before. i advise you to read the article.




回答4:


It's safe, but will break your existing global exception handling. After I did the refactoring, I didn't see any error dialogues anymore, to fix that, I had to subscribe to the Coroutine.Completed event:

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

You can do that in your App.xaml.cs file.

Example from my code on how I handle all possible errors raised in my app:

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

In-case you're wondering, the logger and eventAggregator variables are instantiated from the bootstrapper class in the OnStartup method before calling DisplayRootViewFor.



来源:https://stackoverflow.com/questions/15417354/will-caliburn-micro-do-the-right-thing-with-async-method-on-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!