2014-10-09 107 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