2011-05-03 87 views
1

我有一個關於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

回答

5

我想改寫這個來:

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

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

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

1

我假設你是在不同的線程比創建的單選按鈕之一。否則,調用是沒有意義的。由於您正在該線程中創建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