2014-10-09 77 views
0

我知道这是一个老问题。 这是一些代码。它的工作原理罚款BindingOperations.EnableCollectionSynchronization(Quotes, _stocksLock);如何异步更新到ObservableCollection项目?

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

问题1:在XAML文件有列表视图与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; 
} 

Quetion 2:假设存在一个数据绑定上述button1_Click例子可以用async await来解决,但为什么我不能做某事相似只是用async await

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

更新列表视图错扣?在gui中。我用corss线程错误试了一下。
我以为我搞砸了一些概念。 Plz的帮助。

+0

你的第二个代码示例不应该编译。 'GetStringAsync'返回一个'Task '。由于您不使用'await',编译器应该会发出错误。 – 2014-10-10 08:07:14

+0

@YuvalItzchakov真。让我清楚,第二个代码与其他代码无关。我只是想说明什么时候我认为跨线程发生。我不知道为什么它与数据绑定的情况相同。为什么'等待Task.Run(()=> Quotes.Add(Q));'没有解决问题。 – baozi 2014-10-10 09:35:38

回答

1

为什么我在这里需要EnableCollectionSynchronization?

如果这里你的意思是你的第二个代码示例,比你不需要任何EnableCollectionSynchronization那里。虽然你的第二个例子不会编译,但如果正确完成,将在UI线程上执行label1.Text = result;,并且不会发生跨线程错误。 SynchronizationContext将负责封送回UI线程。

但是,为什么我不能做类似的只是使用异步等待?

我认为你很困惑Task Parallel Libraryasync-await功能的用法。 async-await是一种工具,用于编写异步代码以“缓解疼痛”。 Asynchronousy不是并列:

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

当你的代码structed现在,您不能使用Task.Run更新Quotes,因为它是一个UI绑定属性。

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

+0

我不明白。 'async button1_Click(object sender,EventArgs e){string result = await client。GetStringAsync(“http://microsoft.com”); label1.Text = result;}'工作。在这里用'异步等待'的方式进行封送。 – baozi 2014-10-10 14:15:42

+0

没错。你没有得到什么? – 2014-10-10 14:25:19

+0

为什么'等待Task.Run(()=> Quotes.Add(Q));'没有用于封送到UI线程<这是一个列表视图绑定到行情> – baozi 2014-10-10 15:05:47

相关问题