我已经在wpf中找到了几个关于多线程的主题,并且大多数事情都可以用于调度,但有一件事我还没想到。 我有一个名为“stackpanel1”的stackpanel,我在其中添加了名为“stackrow”的stackpanels(在另一个线程中)作为子项。 (的foreach环)
stackPanel1.Dispatcher.Invoke(new Action(() => stackPanel1.Children.Add(stackrow)));
它类似于这个问题: WPF C# - Editing a listbox from another thread
除了我的“新项目”是一个UI元素(stackrow),我收到以下错误: InvalidOperationException未处理。 调用线程无法访问此对象,因为另一个线程拥有它。
如何在此行中发送“stackrow”?
编辑: stackrow是在foreachloop中创建的
mainthread(创建新线程) 线程t =新线程(()=> addstackrows()); t.SetApartmentState(ApartmentState.STA); t.Start();
方法addstackrows()
private void addstackrows()
{
Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher;
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Children.Clear()));
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Orientation = Orientation.Vertical));
foreach (var randomelement in elementcollection)
{
StackPanel stackrow = new StackPanel();
Dispatcher stackrowdp = stackrow.Dispatcher;
stackrow.Dispatcher.Invoke(new Action(() =>
stackrow.Orientation = Orientation.Horizontal));
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Children.Add(stackrow)));
}
}
答案 0 :(得分:0)
您应该在同一个线程中创建所有UI对象:
private void addstackrows()
{
Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher;
stackPanel1.Dispatcher.Invoke(new Action(() =>
{
stackPanel1.Children.Clear();
stackPanel1.Orientation = Orientation.Vertical;
}));
foreach (var randomelement in elementcollection)
{
stackPanel1.Dispatcher.Invoke(new Action(() =>
{
StackPanel stackrow = new StackPanel();
stackrow.Orientation = Orientation.Horizontal;
stackPanel1.Children.Add(stackrow);
}));
}
}
另外,我会对您的所有Dispatcher
电话进行分组。每次调用Invoke
时都会产生性能开销。因此,除非你在循环中进行耗时的操作,否则最好将整个函数放在Invoke
中。