InvalidOperationException - Objekt wird derzeit anderweitig verwendet - rotes Kreuz
Ich habe ein C# - desktop-Applikation, in der ein thread, erstelle ich ständig bekommt ein Bild von einer Quelle(es ist eine digitale Kamera tatsächlich) und legt es auf ein panel(Bedienfeld.Image = img) in der GUI(die muss einem anderen thread, wie es der code-behind einer Kontrolle.
Funktioniert die Anwendung aber auf einigen Rechnern bekomme ich folgende Fehlermeldung in zufälligen Zeitintervallen(unberechenbar)
************** Exception Text **************
System.InvalidOperationException: The object is currently in use elsewhere.
Dann das panel verwandelt sich in ein rotes Kreuz, rot-X - ich denke, das ist die ungültige Bild-icon, das verändert die Eigenschaften. Die Anwendung funktioniert, aber die Platte wird nie aktualisiert.
Was ich sagen kann, dieser Fehler kommt von der Kontrolle der onpaint-event, wo ziehe ich etwas anderes auf dem Bild.
Versuchte ich mit einem sperren gibt es aber kein Glück 🙁
Die Art, wie ich die Funktion aufrufen, die stellt das Bild auf dem panel ist wie folgt:
if (this.ReceivedFrame != null)
{
Delegate[] clients = this.ReceivedFrame.GetInvocationList();
foreach (Delegate del in clients)
{
try
{
del.DynamicInvoke(new object[] { this,
new StreamEventArgs(frame)} );
}
catch { }
}
}
dies ist die Stellvertretung:
public delegate void ReceivedFrameEventHandler(object sender, StreamEventArgs e);
public event ReceivedFrameEventHandler ReceivedFrame;
und dies ist, wie die Funktion in der control-code-behind-Register:
Camera.ReceivedFrame +=
new Camera.ReceivedFrameEventHandler(camera_ReceivedFrame);
Ich habe auch versucht
del.Method.Invoke(del.Target, new object[] { this, new StreamEventArgs(b) });
statt
del.DynamicInvoke(new object[] { this, new StreamEventArgs(frame) });
aber kein Glück
Weiß jemand, wie könnte ich diesen Fehler beheben oder zumindest fangen die Fehler irgendwie und machen den thread setzen die Bilder auf dem panel wieder?
InformationsquelleAutor der Frage | 2009-06-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist, weil die Gdi+ - Image-Klasse ist nicht thread-sicher. Hovewer, Sie können vermeiden InvalidOperationException durch die Verwendung von lock jedes mal, wenn Sie benötigen, um Zugriff auf Bilder, zum Beispiel für die Lackierung oder das erste Bild Größe:
BTW, Aufruf ist nicht nötig, wenn du dem obigen Muster.
InformationsquelleAutor der Antwort arbiter
Ich hatte ein ähnliches problem mit der gleichen Fehlermeldung, sondern versuchen, wie ich könnte, sperren Sie die bitmap nicht alles reparieren für mich. Dann erkannte ich, ich war zeichnen einer Form mit einer festen Bürste. Sicher genug, es war die Bürste, die war, die den thread Konflikte.
Dieser arbeitete für meinen Fall und Lektion: Überprüfen Sie alle Referenz-Typen verwendet, an der Stelle, wo thread-Konflikte auftreten.
InformationsquelleAutor der Antwort Nick Gotch
Scheint mir, dass die gleiche Kamera-Objekt mehrfach verwendet.
E. g. versuche es mal mit einem neuen Puffer für jeden empfangenen frame. Es scheint mir, dass, während das Bildfeld zeichnen den neuen Rahmen, Ihre capture-Bibliothek füllt die Puffer wieder. Deshalb auf schnellere Maschinen dies könnte nicht ein Problem sein, mit langsameren Rechnern könnte es ein Problem sein.
Habe ich programmiert etwas ähnliches einmal, nach jedem empfangenen frame, mussten wir die Anfrage erhalten, um die nächsten Frames und legen die NEUE frame receive buffer in dieser Anfrage.
Wenn Sie nicht tun können, kopieren Sie die empfangene frame von der Kamera zu einem neuen buffer und fügen die Puffer, eine Warteschlange oder verwenden Sie einfach 2 alternierende Puffer und überprüfen auf überläufe. Entweder myOutPutPanel.BeginInvoke aufrufen, die camera_ReceivedFrame Methode, oder besser ein thread ausgeführt, die überprüft die Warteschlange, wenn es einen neuen Eintrag ruft es mnyOutPutPanel.BeginInvoke aufrufen Ihrer Methode setzen Sie die neuen Puffer als Bild auf dem panel.
Außerdem, sobald Sie erhalten die Puffer, verwenden Sie die Panel-Invoke-Methode zum aufrufen der Einstellung des Bildes (Garantie, dass es läuft in dem Fenster " - thread und nicht der thread aus der capture-Bibliothek).
Kann im folgenden Beispiel aufgerufen werden, aus jedem thread (capture-Bibliothek oder einer anderen separaten thread):
InformationsquelleAutor der Antwort Dennis Kuhn
Ich denke, das ist multithreading-problem
Verwenden Sie windows goldene Regel und aktualisieren Sie das panel in den Haupt-thread benutzen-panel.Aufrufen
Diese überwinden sollte cross-threading Ausnahme
InformationsquelleAutor der Antwort Ahmed Said