10

Я получаю эту ошибку:Что такое родительский замораживаемый? Что означает эта ошибка?

не может использовать DependencyObject, который принадлежит другому потоку, чем его родитель Freezable

Что это значит? Это на английском? Является ли родитель замороженным, или он просто замораживается? Любой способ заставить родителя не замораживаться, если он заставляет проблему уйти?

Что происходит:

У меня есть два OPENGL WinForms элементов управления в приложении WPF, и до сих пор, все это работает гладко (я думаю). Теперь я добавил обновление, чтобы, когда один элемент управления winform обновляет изображение, другой должен также. Это действительно сработало, и теперь я получаю эту ошибку. Пошаговое выполнение кода происходит в случайных местах, что заставляет меня думать, что это ошибка сборки мусора (т. Е. Некоторое обновление в другом потоке создает что-то, что собирает мусор, и эта коллекция происходит в случайное время).

Исключение попадает в метод основного запуска, и это исключение InvalidOperationException.

Я ухватился за соломинку здесь. С чего начать?

EDIT: Похоже, что вызов, который вызывает проблемы это одна:

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

Я по-прежнему отслеживать его вниз; если эта серия строк закомментирована, все равно произойдет сбой, и состояние потока имеет «только что закончившийся» поток (следовательно, предположение о сборке мусора).

+1

Один из немногих случаев, когда предложение диаграмм было бы полезно .. –

+1

Исключительно плохая формулировка названия. Никто не может найти этот вопрос, выполнив поиск по релевантным ключевым словам, поскольку в заголовке нет ни одного. Это не форум поддержки, правильно сформулируйте ваши вопросы ... – Timwi

+1

Эй, @ Тимви, прочитайте ответ. Поймите, что я оставил этот вопрос только потому, что нашел ответ, но это было очень неприятно. Если вы хотите отредактировать название, получите больше отзывов и сделайте это сами, как вы думаете, что это должно быть. – mmr

ответ

12

ОК, я понял это. Обычно я просто удалял этот вопрос, но было больно найти какую-либо информацию о том, как это исправить.

Проблема заключалась в том, что вызов выглядел так:

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(); 
    })); 
} 
Смежные вопросы