WPF跨线程对象访问

本文关键字:访问 对象 线程 WPF | 更新日期: 2023-09-27 17:54:15

我有一个关于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.

我已经尝试了几种解决方法,但都不可行。

感谢任何帮助!

WPF跨线程对象访问

我将重写为:

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;
    }
}));
    r.Dispatcher.Invoke(
      System.Windows.Threading.DispatcherPriority.Normal,
      new Action(
        delegate()
        {
                // DO YOUR If... ELSE STATEMNT HERE
        }
    ));

我假设你是在一个不同的线程比一个创建这些RadioButtons。否则调用就没有意义。因为你在那个线程中创建了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