Threadverhalten
-
Das is was aus der MSDN ... Im Prinzip das Problem zu meiner Lösung ^^
Greetz
-
Manuel schrieb:
Das is was aus der MSDN ... Im Prinzip das Problem zu meiner Lösung ^^
Greetz
Nein. Deine Lösung ist Synchronisation, das Problem ist, dass man Steuerelemente nur aus dem erzeugendem Thread ansprechen darf. Synchronisation ist keine Lösung zu diesem Problem, da Synchronisation immer noch den Zugriff von beliebigen Threads aus erlaubt.
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls(VS.80).aspx
-
private delegate void RetVoidInVoid(); private void makeVisible () { if( this.InvokeRequired ) { this.Invoke( new RetVoidInVoid( makeVisible ) ); } else { lock(this) { test.Visible = true; } } } private void button1_Click(object sender, System.EventArgs e) { makeVisible(); } private void button2_Click(object sender, System.EventArgs e) { Thread t = new Thread ( new ThreadStart ( this.makeVisible ) ); t.Start(); }
Ist net schön, müsste aber funktionieren.
Der Thread ist da ja mal gerade total überflüssig bzw. sehe ich keinen Sinn in dem Thread.^^Edit: Lock hinzugekommen. So jetzt ist das Ding auch Multithread sicher. Was will man mehr?
[Edit]War ein Fehler drin[/Edit]
-
private void makeVisible () { if( this.InvokeRequired ) { this.Invoke( new RetVoidInVoid( makeVisible ) ); return; } else { lock(this) { test.Visible = true; } } }
fänd ich besser.
Übrigens, wenn man lock nutzt, dann möglichst auf kleinster ebene. "this" ist da wohl hochgegriffen. Wie wäre es mitlock(test)
das lock muss aber nicht sein, da du mit den Invoke-Aufruf den Thread schon synchronisierst.
-
Leute, ihr dürft die Steuerelemente nicht aus anderen Threads als dem erzeugenden benutzen, egal wie gut ihr synchronisiert. Euer Code ist vielleicht thread-safe, aber es ist einfach nicht erlaubt.
Es gibt auch praktisch nie einen Grund dafür. Selbst wenn man im Hintergrund arbeiten macht und darauf hin den Zustand eines Steuerelements ändern will ist der Königsweg immer noch eine eigene Windows-Message zu senden, die dann wieder im event handling Thread abgearbeitet wird. Um dies zu erleichtern, gibt es den BackgroundWorker, der das ganze Message-Gefriemel übernimmt.
-
Optimizer schrieb:
Leute, ihr dürft die Steuerelemente nicht aus anderen Threads als dem erzeugenden benutzen, egal wie gut ihr synchronisiert. Euer Code ist vielleicht thread-safe, aber es ist einfach nicht erlaubt.
Es gibt auch praktisch nie einen Grund dafür. Selbst wenn man im Hintergrund arbeiten macht und darauf hin den Zustand eines Steuerelements ändern will ist der Königsweg immer noch eine eigene Windows-Message zu senden, die dann wieder im event handling Thread abgearbeitet wird. Um dies zu erleichtern, gibt es den BackgroundWorker, der das ganze Message-Gefriemel übernimmt.So wie es von AndreasW gemacht wurde, wird aber auch von Microsoft vorgeschlagen und ich finde das eine gute Lösung.
-
AndreasW schrieb:
Übrigens, wenn man lock nutzt, dann möglichst auf kleinster ebene. "this" ist da wohl hochgegriffen. Wie wäre es mit
lock(test)
das lock muss aber nicht sein, da du mit den Invoke-Aufruf den Thread schon synchronisierst.
ja das ist ja wohl geschmackssache... Da muss halt nur irgendeine globale Variable rein und da habe ich mal this genommen. Man könnte natürlich auch ein "Object SyncRoot = new Object();" nehmen. So habe ich das auch mal in einem Quellcode von Microsoft gesehen
Optimizer schrieb:
Leute, ihr dürft die Steuerelemente nicht aus anderen Threads als dem erzeugenden benutzen, egal wie gut ihr synchronisiert.
Yep da gebe ich dir zu 100% recht. Das ist nicht zulässig.
Aber...
Optimizer schrieb:
Es gibt auch praktisch nie einen Grund dafür. Selbst wenn man im Hintergrund arbeiten macht und darauf hin den Zustand eines Steuerelements ändern will ist der Königsweg immer noch eine eigene Windows-Message zu senden, die dann wieder im event handling Thread abgearbeitet wird. Um dies zu erleichtern, gibt es den BackgroundWorker, der das ganze Message-Gefriemel übernimmt.
Falsch!!! Ließ mal nach wofür das Invoke bei Steuerlementen da ist. Nämlich genau dafür. Das Invoke sagt dem Gui-Thread das er die Methode ausführen soll, wenn er halt mal zeit hat.
Und Gründe wo man sowas braucht kann ich dir 100 Tausend liefern. Ich komme aus der Praxis und da braucht man sowas halt.
-
Das Invoke habe ich irgendwie übersehen. Ich dachte, es würde nur der Zugriff synchronisiert, dass er aber immer noch verschiedenen Threads aus stattfindet. Sorry, da war ich auf dem falschen Dampfer.
Das Invoke ist ja natürlich auch genau das, eine Windows Message zu senden, die dann im event thread abgearbeitet wird.
-
Optimizer schrieb:
Das Invoke habe ich irgendwie übersehen.
Entschuldige, aber ... Held...
Greetz
-
Manuel schrieb:
Optimizer schrieb:
Das Invoke habe ich irgendwie übersehen.
Entschuldige, aber ... Held...
Greetz
lol kann doch passieren:D
-
de_Bert schrieb:
Manuel schrieb:
Optimizer schrieb:
Das Invoke habe ich irgendwie übersehen.
Entschuldige, aber ... Held...
Greetz
lol kann doch passieren:D
^^
Klar kanns das ... nur sein rechthaberische Gehabe hat mir nich gefallen ...Greetz und schönen Abend noch