我有一个WPF应用程序,我想在许多线程上向listbox添加项目。 当我做这样的事情时
listBox.Items.Clear();
var lastgames = db.GameResults.OrderByDescending(c => c.DataGry).ToList();
Parallel.ForEach(lastgames, game =>
{
listBox.Items.Add(game.score);
});
它显然会抛出异常
调用线程无法访问此对象,因为另一个线程拥有它。
我听说过WPF中的后台工作者,但我不知道如何使用它。
答案 0 :(得分:0)
您不能使用UI线程以外的其他线程的UI控件。你应该使用调度员。
例如:
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
listBox.Items.Add(game.score);
}));
答案 1 :(得分:0)
由于UI元素只能从最初创建它们的线程(即UI线程)访问,因此使用Parallel.ForEach
将项添加到ListBox是没有意义的。
你应该使用一个简单的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循环并在同一个线程上添加所有项目。