Laden...

Threadübergreifender Vorgang trotz InvokeRequired

Erstellt von Programmierhans vor 17 Jahren Letzter Beitrag vor 17 Jahren 8.708 Views
Information von herbivore vor 12 Jahren

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 17 Jahren
Threadübergreifender Vorgang trotz InvokeRequired

Keywords: InvokeRequired ISynchronizeInvoke IsHandleCreated CreateHandle

Ausgangslage:

Wenn eine CrossThreadException auftritt (2.0) oder das UI usw. völlig unerwartet blockiert (1.1). Dann ist daran oft ein Zugriff auf UI-Controls aus einem nicht UI-Thread schuld.

Dies kann man ja relativ einfach verhindern indem man das Zielcontrol auf InvokeRequired abfragt und gegebenenfalls den Call in den UI-Thread marshallt (Suchbegriff InvokeRequired).

Es ist aber tatsächlich möglich, dass diese Situation auftritt OBWOHL man InvokeRequired abgefragt hat und dieses Property false zurückliefert.

Wie ist dies möglich, und was kann man dagegen tun ?

Hintergrund:

InvokeRequired vergleicht normalerweise den Thread des UI-Controls mit dem Thread des callers. Wenn es sich um 2 verschiedene Threads handelt, dann returniert InvokeRequired true.

Nun die Falle:

Wenn das Handle des ZielControls noch nicht erstellt ist (IsHandleCreated=false), dann kann der Vergleich noch nicht stattfinden.... InvokeRequired gibt dann false zurück (getestet in 1.1). Wenn jetzt ein direkter Call auf das UI-Control (aus einem nicht UI-Thread) stattfindet, dann entsteht dieses Problem.

Lösung:

Ein InvokeRequired ergibt nur einen sinnvollen Wert, wenn das Handle bereits erstellt ist... anderenfalls kann man z.B: mit base.CreateHandle() die Erstellung des Handles forcieren bevor man InvokeRequired abfragt.

Schlusswort:

Die wenigsten von euch werden wohl je mit diesem Problem konfrontiert... da das Timing doch relativ knapp sein muss damit man in diese Falle tappen kann. (z.B: ein Methode wird aus einem anderen Thread aufgerufen BEVOR das Control (oder Form) vollständig erstellt ist (z.B: Thread im Constructor gestartet).....

Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...