WPF跨线程对象访问

问题描述:

我有一个关于WPF中的跨线程调用的问题。WPF跨线程对象访问

  foreach (RadioButton r in StatusButtonList) 
     { 
      StatusType status = null; 
      r.Dispatcher.Invoke(new ThreadStart(() => status= ((StatusButtonProperties)r.Tag).StatusInformation)); 
      if (AppLogic.CurrentStatus == null || AppLogic.CurrentStatus.IsStatusNextLogical(status.Code)) 
      { 
       SolidColorBrush green = new SolidColorBrush(Color.FromRgb(102, 255, 102)); 
       r.Dispatcher.Invoke(new ThreadStart(() => r.Background = green)); 
      } 
      else 
      { 
       SolidColorBrush red = new SolidColorBrush(Color.FromRgb(255, 0, 0)); 
       r.Dispatcher.Invoke(new ThreadStart(() => r.Background = red)); 
      } 
     } 

当我运行此代码时,它在第一次迭代中正常工作。然而在第二次迭代行:

r.Dispatcher.Invoke(new ThreadStart(() => status= ((StatusButtonProperties)r.Tag).StatusInformation)) 

导致此异常:

Cannot use a DependencyObject that belongs to a different thread than its parent Freezable. 

我已经尝试了一些解决方案,但我找不到任何可行的。

任何帮助表示赞赏!

+2

在与r.Dispatcher.Invoke不同的线程中创建SolidColorBrush红色+绿色...? – 2011-05-03 11:04:42

+0

为什么你使用这些设置器的新线程?由于您正在使用Invoke(),因此它会阻塞,直到该线程完成其工作,因此它可能会减慢整个过程。 – 2011-05-03 11:06:55

我想改写这个来:

r.Dispatcher.Invoke(new Action(delegate() 
{ 
    status = ((StatusButtonProperties)r.Tag).StatusInformation; 

    if (AppLogic.CurrentStatus == null || AppLogic.CurrentStatus.IsStatusNextLogical(status.Code)) 
    { 
     r.Background = Brushes.Green; 
    } 
    else 
    { 
     r.Background = Brushes.Red; 
    } 

})); 
+0

也适用,谢谢! – 2011-05-03 11:12:56

r.Dispatcher.Invoke(
     System.Windows.Threading.DispatcherPriority.Normal, 
     new Action(
     delegate() 
     { 
       // DO YOUR If... ELSE STATEMNT HERE 
     } 
    )); 
+0

完美地工作,谢谢! – 2011-05-03 11:12:26

我假设你是在不同的线程比创建的单选按钮之一。否则,调用是没有意义的。由于您正在该线程中创建SolidColorBrush,因此您已经有可能的跨线程调用。

使交叉线程调用更“块”,即将所有内容放在foreach循环中进行单个Invoke调用会更有意义。

foreach (RadioButton r in StatusButtonList) 
{ 
    r.Dispatcher.Invoke(new ThreadStart(() => 
     { 
      StatusType status = ((StatusButtonProperties)r.Tag).StatusInformation; 
      if (AppLogic.CurrentStatus == null || AppLogic.CurrentStatus.IsStatusNextLogical(status.Code)) 
      { 
       SolidColorBrush green = new SolidColorBrush(Color.FromRgb(102, 255, 102)); 
       r.Background = green; 
      } 
      else 
      { 
       SolidColorBrush red = new SolidColorBrush(Color.FromRgb(255, 0, 0)); 
       r.Background = red; 
      } 
     }); 
} 

如果不同的调用不是互相依赖的,你也可以考虑使用BeginInvoke