2009-05-14 12 views
10

Ich erhalte diese Fehlermeldung:Was ist ein Elternteil freezable? Was bedeutet dieser Fehler?

kann nicht DependencyObject verwenden, die als seine Eltern bedeutet Was Freezable

zu einem anderen Thread gehört, dass selbst? Ist es auf Englisch? Ist das Elternteil eingefroren, oder ist es nur gefrierfähig? Irgendeine Möglichkeit, ein Elternteil nicht zu frieren, wenn es den Fehler aufhebt?

Was passiert:

Ich habe zwei opengl WinForms-Steuerelemente in einer WPF-Anwendung, und so weit, alles ist schon reibungslos funktioniert (ich glaube). Jetzt habe ich ein Update hinzugefügt, so dass wenn ein Winform-Steuerelement das Bild aktualisiert, das andere auch. Das hat früher funktioniert, und jetzt bekomme ich diesen Fehler. Beim Durchlaufen des Codes passiert der Absturz an zufälligen Stellen, was mich zu der Annahme verleitet, dass es sich um einen Garbage-Collection-Fehler handelt (dh einige Updates in einem anderen Thread erstellen etwas, das Müll sammelt und diese Sammlung zu einer zufälligen Zeit stattfindet).

Die Ausnahme wird in der Hauptlaufmethode abgefangen und ist eine InvalidOperationException.

Ich fasse hier Strohhalme. Wo soll ich anfangen?

EDIT: Es sieht aus wie der Anruf, der das Problem verursacht ist dieses:

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

ich Tracking es immer noch nach unten; Wenn diese Reihe von Zeilen auskommentiert wird, tritt der Absturz immer noch auf, und der Thread-Status hat einen Thread "gerade beendet" (daher die Annahme der Speicherbereinigung).

+1

Einer der wenigen Fälle, in denen ein Satz diagramming wäre hilfreich .. –

+1

Äußerst schlechte Titelformulierung. Niemand kann diese Frage finden, indem er nach relevanten Stichwörtern sucht, da keine im Titel enthalten sind. Dies ist kein Support-Forum, formuliere deine Fragen richtig ... – Timwi

+1

Hey @Timwi, lies die Antwort. Erkenne, dass ich diese Frage nur hier gelassen habe, weil ich die Antwort gefunden habe, aber es war extrem frustrierend. Wenn Sie den Titel bearbeiten möchten, erhalten Sie mehr Rep und tun Sie es selbst für wie Sie denken, dass es sein sollte. – mmr

Antwort

12

OK, ich habe es herausgefunden. Normalerweise würde ich diese Frage einfach löschen, aber es war ein Schmerz, Informationen darüber zu finden, wie ich das beheben kann.

Das Problem war ein Anruf, der so aussah:

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

Aber! Wenn Sie das tun, arbeitet der Dispatcher und versucht dann, den Pinsel zu löschen, aber der Pinsel selbst wird anscheinend auch an einem anderen Ort gelöscht.

Also, die Take-Home-Lektion ist, wenn Sie eine ImageBrush erklären, löschen Sie es dann im selben Thread, etwa so:

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