Wpf 无法使用DependencyObject,该对象属于与其父Freezable不同的线程

Wpf 无法使用DependencyObject,该对象属于与其父Freezable不同的线程,wpf,multithreading,backgroundworker,dispatcher,Wpf,Multithreading,Backgroundworker,Dispatcher,WPF-我正在使用BackgroundWorker创建Model3D对象,但当我想将其添加到XAML中定义的Model3DGroup中时,会出现异常: 无法使用属于其父Freezable之外的其他线程的DependencyObject 这就是背后的全部代码: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Backgrou

WPF-我正在使用BackgroundWorker创建Model3D对象,但当我想将其添加到XAML中定义的Model3DGroup中时,会出现异常:

无法使用属于其父Freezable之外的其他线程的DependencyObject

这就是背后的全部代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync();
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        GeometryModel3D geometryModel3D = (GeometryModel3D)e.Result;
        model3DGroup.Children.Add(geometryModel3D);
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        GeometryModel3D geometryModel3D = new GeometryModel3D();
        e.Result = geometryModel3D;
    }
}
这就是整个XAML:

    <Grid>
    <Viewport3D Margin="4,4,4,4" Grid.Row="0" Grid.Column="0">
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup x:Name="model3DGroup">
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>
</Grid>

在RunWorkerCompleted处理程序中,您正在向Model3DGroup添加GeometryModel3D实例,该实例显然是在UI线程以外的线程中创建的,因为BackgroundWorker.DoWork处理程序是在单独的线程中执行的

简而言之,正如您可能从异常消息中注意到的,WPF不允许这样做。应用程序中的所有UI元素,或者更准确地说,所有派生对象都必须在同一线程中创建

了解WPF的概述,并参阅文档中的备注部分

编辑:但是,您可以通过同步调用MainWindow类的创建新的GeometryModel3D实例(无需测试):

private void bw\u DoWork(对象发送方,DoWorkEventArgs e)
{   
e、 结果=Dispatcher.Invoke(
(Func)(()=>新几何模型3D());
}   

您可以在单独的线程中创建Model3D几何体。但在创建后将其冻结。然后,RunWorkerCompleted方法可以简单地克隆冻结的几何体(尽管如果Model3D包含纹理,我无法使其工作)。

在我的情况下,我是在一个新的调度程序线程上创建一个新的WPF窗口

在一个最小的WPF项目中,所有的工作都非常完美,但是如果我将相同的代码移植到我们的大型生产WPF代码库中,它就失败了

问题是有一些继承的对象绑定到错误线程上的某个对象

我在受影响的UserControl中使用此选项可以避免此错误:

public MyUserControl()
{
    // Discard all inherited styles.
    this.InheritanceBehavior = InheritanceBehavior.SkipAllNow;

    this.InitializeComponent();
}
现在我已经让它工作了,我可以找出哪个样式或附加的属性具有到另一个线程的隐藏绑定,这是导致此问题的原因

更新 问题是一些资源没有被冻结。此处引用了有问题的资源:

ResourceDictionary resources = Application.Current.Resources;
foreach (var resource in resources)
{
   // The offending resource (a scrollbar) is listed here.                
}

你知道答案了吗?我知道问题出在哪里,但不知道如何解决。后来,我尝试了简单的线程而不是后台工作。。似乎它对我有效,我希望我能用backgroundworkerWell做到这一点,你在这里简单地描述了你的程序错误,但没有问任何问题。我已经解释了哪里出了问题,现在由你来接受这个答案,并尝试解决你的问题,当你遇到更多的麻烦时,再问另一个问题。否则人们可能会失去帮助你的乐趣。请参阅我编辑的答案。也许这会有帮助。你现在得到答案了吗?我有一个类似的问题(相同的错误消息),那就是使用
dispatcher.Invoke
。。。
ResourceDictionary resources = Application.Current.Resources;
foreach (var resource in resources)
{
   // The offending resource (a scrollbar) is listed here.                
}