MVVM中异步是什么?在Model或ViewModel中?最佳实践是什么?

5
我正在寻找异步通信的最佳实践,以在层之间进行通信。 我正在使用mvvm light toolkit。 目前,我在model中使用backgroundworker,因为我在自动生成的代码中看到了这一点。不是用backgroundworker,而是使用异步调用。
public void GetConfig(Action<Config, Exception> callback)
{
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += (backgroundWorkerSender, backgroundWorkerArgs) =>
    {
        try
        {
            backgroundWorkerArgs.Result = AppEnvironment.Instance.Config;
        }
        catch (Exception exception)
        {
            backgroundWorkerArgs.Result = null;
        }
    };

    backgroundWorker.RunWorkerCompleted += (backgroundWorkerSender, backgroundWorkerArgs) =>
    {
        if (backgroundWorkerArgs.Result != null)
        {
            callback((Config) backgroundWorkerArgs.Result, null);
        }
        else
        {
            /* ToDo: exceptionhandling */
        }
    };

    backgroundWorker.RunWorkerAsync(); 
}

现在我找到了AsyncDelegateCommand,它在ViewModel中实现了异步部分。

private ICommand _refreshObjectDefinitionCommand;
public ICommand RefreshObjectDefinitionCommand
{
    get
    {
        return _refreshObjectDefinitionCommand
          ?? (_refreshObjectDefinitionCommand = new AsyncDelegateCommand(delegate
              {
                  IsBusy = true;
                  _dataService.GetObjectDefinition(
                    (xmlObjectDef, errorConfig) =>
                    {
                        if (errorConfig != null)
                        {
                            /* ToDo Lenz: exceptionhandling */
                            return;
                        }

                        ObjectDefinition = xmlObjectDef;
                    });

                  _dataService.GetObjectDefinitionTreeView(
                      (treenodes, errorConfig) =>
                      {
                          if (errorConfig != null)
                          {
                              /* ToDo Lenz: exceptionhandling */
                              return;
                          }

                          TreeNodes = treenodes;
                      });
              },
                                () => _isConnected, o => IsBusy = false, exception => IsBusy = false));
    }
}

我有点困惑最佳实践是什么? 我读了很多文章,但它们总是存在不同的观点。 在通常的维护工作量下,是否有最佳兼容性的规定?

思考一下:

模型:

http://csharperimage.jeremylikness.com/2009/12/simplifying-asynchronous-calls-in.html

http://www.dzone.com/articles/mvvmlight-and-async

视图模型:

http://www.codeproject.com/Articles/123183/Asynchronus-MVVM-Stop-the-Dreaded-Dead-GUI-Problem

http://www.codeproject.com/Articles/441752/Async-MVVM-Modern-UI


任务模式不使用async/await会更难读懂,不是吗? - JustAnotherUserYouMayKnow
当然,但据我所知,这只在.net 4.5之后才可用?!? - masterchris_99
有一个 NuGet 包支持 4.0 和 Silverlight 5。将其安装到您的项目中,它会像魔法一样工作!http://nuget.org/packages/Microsoft.CompilerServices.AsyncTargetingPack/ - JustAnotherUserYouMayKnow
2个回答

1
我建议将异步代码放在您的ViewModel中,而将Model保留用于存储数据。当我开始学习MVVM时,我学到的第一件事就是从我的Models中删除逻辑,并将其保留在我的ViewModels中。虽然我会说,只要所有阅读代码的人都能理解它,那么您放置代码的位置并不重要。

1

我认为将模型获取并转换为视图模型是异步的。谁来做,取决于架构,可以在视图模型本身上完成,也可以使用控制器层进行这样的异步加载和初始化VM到视图的映射。此外,后台工作者已经过时,你应该使用Task类进行并行操作。当从VM通知视图发生更改时,当然不要忘记通过调度程序调用。

代码示例:

    Task<string>.Factory.StartNew(() =>
{
     string text = GetArticleText();
     Application.Current.Dispatcher.BeginInvoke(new Action(()=>MyTextProperty = text));   
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接