从另一个线程向堆栈面板添加stackpanel(带分派?)

时间:2013-05-31 21:07:08

标签: c# wpf multithreading dispatcher

我已经在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)));

  }

}

1 个答案:

答案 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中。