异步Task.Run与MVVM [英] async Task.Run with MVVM

查看:199
本文介绍了异步Task.Run与MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在用新的异步CTP和MVVM模式玩耍。我一直认为转换使用后台工作,并报告进展情况在我的模型更新收集我的一个老程序。我把它转换为类似这样

I have been playing around with the new async CTP and MVVM patterns. I have been converting an old program of mine that was using a background worker and report progress to update a collection in my model. I have converted it to something like so

TaskEx.Run(async () =>
{
  while (true)
  {
    // update ObservableCollection here
  }
  await TaskEx.Delay(500);
});

在我看来,我绑定到我的视图模型暴露出该观察的集合。然而,当我收集的更新,我得到了以下异常

In my view I bind to my viewmodel which exposes this observable collection. However, when my collection updates I get the following Exception

这类型的CollectionView不支持从一个线程从调度线程不同其SourceCollection变化。

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

我不知道该怎么拉正确的方法是回到UI线程时这样做。

I'm not sure what the correct way to pull the is back to the UI thread when done like this.

推荐答案

您不必使用运行异步方法 Task.Run(),或任何其他特殊意味着,只要给他们打电话。而在你的情况,这究竟是什么导致了问题。

You don't have to run async methods using Task.Run(), or any other special means, just call them. And in your case, that's exactly what is causing the problem.

由于功能是这样的:

Action f = async () =>
{
    while (true)
    {
        // modify the observable collection here
        await Task.Delay(500);
    }
};

调用它像这样从UI线程上的一些方法来看,像一个事件处理程序:

Calling it like this from some method run on the UI thread, like an event handler:

f();

正好可以作为它应该。它执行周期的第一次迭代,然后返回。下一个迭代后500毫秒执行(或更多,如果UI线程繁忙)在UI线程上。

works exactly as it should. It executes the first iteration of the cycle and then returns. The next iteration is executed after 500 ms (or more, if the UI thread is busy) on the UI thread.

在另一方面,如果你把它是这样的:

On the other hand, if you call it like this:

Task.Run(addNames);

它不能正常工作。这样做的原因是,异步方法尝试在同样的情况下,继续当他们开始了(除非你明确指定其他)。第一个版本开始在UI线程上,所以它继续在UI线程上。第二个版本上的线程池线程开始(感谢 Task.Run()),并继续有太多。这就是为什么它造成的错误。

it doesn't work correctly. The reason for this is that async methods try to continue in the same context as they were started (unless you explicitly specify otherwise). The first version was started on the UI thread, so it continued on the UI thread. The second version started on a ThreadPool thread (thanks to Task.Run()) and continued there too. Which is why it caused your error.

这一切都使用做 的SynchronizationContext ,如果​​一个人是present。

All this is done using SynchronizationContext, if one is present.

这篇关于异步Task.Run与MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆