我知道这是一个老问题。
这是一些代码。它适用于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帮助。
答案 0 :(得分:1)
为什么我在这里需要EnableCollectionSynchronization?
如果通过此处表示您的第二个代码示例,那么您不需要任何EnableCollectionSynchronization
。虽然您的第二个示例不会编译,但如果操作正确,将在UI线程上执行label1.Text = result;
,并且不会发生跨线程错误。 SynchronizationContext
将负责编组工作回到UI线程。
但为什么我只能使用async await来做类似的事情呢?
我认为您混淆了Task Parallel Library
和async-await
功能的使用。 async-await
是一种能够缓解疼痛的工具。编写异步代码。异步不是平行的:
当你异步运行它意味着它是非阻塞的时,你执行它而不等待它完成并继续其他的事情。并行意味着同时运行多个事物。
由于您的代码现在正在构建,因此您无法使用Task.Run
来更新Quotes
,因为它是一个UI绑定属性。
大多数情况下,您会发现使用async-await
自然地使用I / O绑定操作。