C# WPF跨线程对象访问

C# WPF跨线程对象访问,c#,.net,wpf,multithreading,C#,.net,Wpf,Multithreading,我对WPF中的跨线程调用有一个问题 foreach (RadioButton r in StatusButtonList) { StatusType status = null; r.Dispatcher.Invoke(new ThreadStart(() => status= ((StatusButtonProperties)r.Tag).StatusInformation));

我对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.
我试过一些解决办法,但找不到任何可行的办法

感谢您的帮助

我将此重写为:

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

}));

我假设你所处的线程与创建这些单选按钮的线程不同。否则调用就没有意义了。由于您正在该线程中创建SolidColorBrush,因此已经有了一个潜在的跨线程调用

让跨线程调用更“粗块”更有意义,即将foreach循环中的所有内容放在一个调用中

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;
            }
        });
}

你也可以考虑使用<代码>开始调用< /COD>如果不同的调用不是相互依赖的。

< p>我假设你处于与创建这些按钮的线程不同的线程中。否则调用就没有意义了。由于您正在该线程中创建SolidColorBrush,因此已经有了一个潜在的跨线程调用

让跨线程调用更“粗块”更有意义,即将foreach循环中的所有内容放在一个调用中

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;
            }
        });
}

您也可以考虑使用不同的调用不是相互依赖的.<代码> NeXPojKe>代码> .< /P>在一个与R.Debug……不相同的线程中创建StultCyrBuffRe+Green。为什么您要为这些设置器使用一个新线程?由于您使用的是Invoke(),它会一直阻塞,直到该线程完成其工作,因此可能会减慢整个进程。在与r.Dispatcher不同的线程中创建SolidColorBrush red+green。Invoke…?为什么要为这些setter使用新线程?因为您使用的是Invoke(),所以在该线程完成其工作之前,它一直处于阻塞状态,因此它可能会减慢整个进程的速度。