-1

我已经在 wpf 中找到了几个关于多线程的主题,并且大多数事情都可以与 dispatch 一起使用,但有一件事我还没有弄清楚。我有一个名为“stackpanel1”的堆栈面板,我在其中添加了名为“stackrow”的堆栈面板(在另一个线程中)作为子级。(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(创建新线程) Thread t = new Thread(()=> 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)));

  }

}
4

1 回答 1

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.

于 2013-05-31T22:08:33.197 回答