由於UI元素只能從他們最初的創建上,即UI線程的線程進行訪問,這是沒有意義的使用Parallel.ForEach
項添加到列表框。
你應該用一個簡單的foreach循環:
listBox.Items.Clear();
var lastgames = db.GameResults.OrderByDescending(c => c.DataGry).ToList();
foreach(var game in lastgames)
listBox.Items.Add(game.score);
另一種選擇是將商品加入一個線程安全的集合,然後設置ListBox的ItemsSource屬性來此集合一旦被填充:
object _lock = new _lock();
List<int> scores = new List<int>();
listBox.Items.Clear();
var lastgames = db.GameResults.OrderByDescending(c => c.DataGry).ToList();
Parallel.ForEach(lastgames, game =>
{
lock (_lock)
scores.Add(game.score);
});
listBox.ItemsSource = scores;
雖然你仍然需要在循環的每次迭代中同步對集合的訪問,但這樣做毫無意義。所以你最好使用一個簡單的foreach循環,並將所有項目添加到同一個線程中。
來源
2017-02-05 10:53:32
mm8
你不能觸及UI線程以外的其他線程的UI對象...你可以在WinForms上使用Invoke,或者在wpf中使用Dispatcher ...但是你應該使用MVVM這樣的好模式來修改ViewModel和視圖反映視圖模型中的變化......不編寫邏輯將項目直接添加到UI控件中 –
要處理導致UI被鎖定的長操作或操作,您需要使用「ThreadPool」和「Dispatcher.Invoke」。例如:http://stackoverflow.com/questions/36521365/run-program-after-wpf-windows-form-appears –
@ S.Akbari一直使用你的代碼,並替換parallel.foreach到正常的foreach是我應該做的? – kociolekpanoramixa