如何异步更新ObservableCollection项?

时间:2014-10-09 17:30:31

标签: c# async-await observablecollection

我知道这是一个老问题。 这是一些代码。它适用于BindingOperations.EnableCollectionSynchronization(Quotes, _stocksLock);

private void _source_QuoteArrived(Quote Q)
{
    Quotes.Add(Q);
}

问题1:在xaml文件中,listview与Quotes绑定。但为什么在这里发生交叉线程?我对交叉线程的理解只有在你明确地做到这一点时才会发生。像下面的例子。当您明确使用UI元素(此处为label1)时,会发生穿越线程错误。但我在这里使用数据绑定是双向的。为什么我在这里需要EnableCollectionSynchronization

 private  void button1_Click(object sender, EventArgs e)
 {
     HttpClient client = new HttpClient();
     string result =  client.GetStringAsync("http://microsoft.com");
     label1.Text = result;
 }

问题2:假设存在带数据绑定的交叉线程?上面的button1_Click示例可以通过async await来解决但是为什么只能使用async await <做类似的事情? / p>

private async void _source_QuoteArrived(Quote Q)
{
    await Task.Run(() => Quotes.Add(Q));
}

更新gui中的listview。我用corss线程错误尝试了它 我以为我搞砸了一些概念。 Plz帮助。

1 个答案:

答案 0 :(得分:1)

  

为什么我在这里需要EnableCollectionSynchronization?

如果通过此处表示您的第二个代码示例,那么您不需要任何EnableCollectionSynchronization。虽然您的第二个示例不会编译,但如果操作正确,将在UI线程上执行label1.Text = result;,并且不会发生跨线程错误。 SynchronizationContext将负责编组工作回到UI线程。

  

但为什么我只能使用async await来做类似的事情呢?

我认为您混淆了Task Parallel Libraryasync-await功能的使用。 async-await是一种能够缓解疼痛的工具。编写异步代码。异步不是平行的:

  

当你异步运行它意味着它是非阻塞的时,你执行它而不等待它完成并继续其他的事情。并行意味着同时运行多个事物。

由于您的代码现在正在构建,因此您无法使用Task.Run来更新Quotes,因为它是一个UI绑定属性。

大多数情况下,您会发现使用async-await自然地使用I / O绑定操作。