什么是父母可冻结?这个错误是什么意思?

问题描述 投票:11回答:1

我得到这个错误。

Cannot use a DependencyObject that belongs to a different thread than its parent Freezable 无法使用一个与父Freezable不同的线程的DependencyObject。

这到底是什么意思? 是用英文写的吗? 母体是被冻结的,还是只是可冻结的? 有什么办法可以让父体不被冻结,如果让错误消失?

发生了什么事情。

我在一个WPF应用程序里有两个opengl winforms控件 到目前为止,一切都很顺利(我想)。 现在,我添加了一个更新,所以当一个winform控件更新图像时,另一个也应该更新。 这实际上曾经工作过,但现在我得到了那个错误。 通过代码,崩溃发生在随机的地方,这让我相信这是一个垃圾收集故障(即,在另一个线程中的一些更新正在创建一些被垃圾收集的东西,而收集发生在一个随机的时间)。

异常是在主运行方法中捕获的,是一个InvalidOperationException。

我正在抓紧时间。 我应该从哪里开始呢?

EDIT: 看起来导致问题的是这个调用。

        if (imagePanel.InvokeRequired)
        {
            imagePanel.Invoke(new System.Windows.Forms.MethodInvoker(delegate{
                imagePanel.ClearImages();
            }));
        }
        else
        {
            imagePanel.ClearImages();
        }

我还在追踪它;如果这一系列行被注释掉,崩溃还是会发生,而且线程状态有一个 "刚刚结束 "的线程(所以才有垃圾收集的假设)。

wpf invalidoperationexception dependencyobject freezable
1个回答
14
投票

好了,我想明白了。 一般情况下,我会直接删掉这个问题,但是找不到任何关于如何解决这个问题的信息,很麻烦。

问题是一个电话,看起来是这样的。

ImageBrush theBrush = new ImageBrush(new Bitmap(new Uri(...)));

if (labelStatus.Dispatcher.Thread == System.Threading.Thread.CurrentThread) {
    button.background = theBrush;
}
else {
   labelStatus.Dispatcher.BeginInvoke((System.Threading.ThreadStart)(delegate {
    button.background = theBrush;
   }));
}

但是,如果你这样做,然后调度器的工作, 然后它试图删除刷子, 但刷子本身显然也被删除 在另一个位置。

所以,总结的经验是,如果你声明一个ImageBrush,然后在同一个线程中删除它,像这样。

void MyFunc(){
     ImageBrush theBrush = new ImageBrush(new Bitmap(new Uri(...)));
     button.background = theBrush;
}

if (labelStatus.Dispatcher.Thread == System.Threading.Thread.CurrentThread) {
    MyFunc();
}
else {
   labelStatus.Dispatcher.BeginInvoke((System.Threading.ThreadStart)(delegate {
       MyFunc();
   }));
}
© www.soinside.com 2019 - 2024. All rights reserved.