我有一个关于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.
我尝试了一些解决方案,但找不到任何可行的方法。
任何帮助表示赞赏!
答案 0 :(得分: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;
}
}));
答案 1 :(得分:3)
r.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
// DO YOUR If... ELSE STATEMNT HERE
}
));
答案 2 :(得分:1)
我假设你所处的线程与创建那些RadioButton的线程不同。否则调用没有意义。由于您在该线程中创建了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
。