Thread hängt bei schießen der Aplikation
-
Hallo Leute,
ich habe ein WPF Anwendung, in der ich eine Thread verwendet, welcher Daten pollt. Dabei wird eine API (AG Link) verwendet.
Pseudo:
_thread = new Thread(ThreadFunc); _manualResetEvent = new ManualResetEvent(false); _thread.Start(); .... private void ThreadFunc() { do { ReadDataWithAGLink(); } while (!_manualResetEvent.WaitOne(100)); } ... public void Dispose() { _manualResetEvent.Set(); while (_thread.IsAlive) Thread.Sleep(100); }
Wenn ich die Anwendung schließe, wird schön Dispose aufgerufen, aber nun hängt der Prozess ewig in der IsAlive while. und die Anwendung is eingefrohren (bis man den prozess in taskmanager killt)
Folgendes is mir aufgefallen:
1. Wenn ich nun im in VS auf Pause drücke , und in den Thread wechsel, steht der Thread immer in einer AG-Link API Funktion. Wenn ich dann wieder Start drücke, beendet sich plötzlich der Thread ordnungsgemäß!? ansonst hängt es ewig...
2. Wenn ich
while (_thread.IsAlive) Thread.Sleep(100);
auskommentiere. Dann schließt sich die Anwendung, auch und im Taskmanager sehe ihc, dass sich der Prozess paar Sekunden auch auflöst!
Vll. noch was am Rande, ich schicke daten an die GUI via Dispater.Invoke.. vll. is das auch noch ein Problem!?
-
Nochwas:
Ich rufe in diesem Thread den Dispatcher auf!
Wenn ich nun Dispatcher.BeginInvoke statt Dispatcher.Begin aufruffe , klappt es !?
Woran könnte das liegen, beim beenden des Thread steht das Problem im Dispatcher.Invoke anrufe.. gibt es da nen "dealook" oder so was!?
Grüßele
-
Du scheinst wirklich wenig Ahnung von Multithreading-Programmierung zu haben.
Statt manuellen Threads und Locking, warum nutzt du nicht Tasks?
-
Oh bitte, das ist eines der ältesten Probleme beim Thema Multithreading. Wenn nicht sogar DAS Problem.
Ja, natürlich kann sich das Programm dadurch deadlocken.
Dein Thread wartet in Invoke dass der Main-Thread sein "Invoke" berabeitet.
Und dein Main-Thread wartet währenddessen in derwhile (_thread.IsAlive)
Schleife dass dein Thread sich beendet.
Wie soll jetzt einer der beiden Threads weiterkommen? Kann nicht gehen.
-
Und dein Main-Thread wartet währenddessen in der while (_thread.IsAlive) Schleife dass dein Thread sich beendet.
Wie soll jetzt einer der beiden Threads weiterkommen? Kann nicht gehen.Ohhh nein.. peinlich.. aber ein sehendes Huhn findet mal kein Korn;)
-
Pack ich meine polling Loop in nen Task, statt in nen Thread, gibts da nen unterscheid was das Problem angeht?
-
Wenn du Invoke machst, dann muss der Main-Thread im Message-Loop laufen - sonst wird Invoke ewig warten.
Wenn das OK ist, dann kannst du z.B. im entsprechenden "User hat X geklickt" Handler (weiss jetzt nicht auswendig wie der heisst) den Event setzen, und z.B. nen Timer starten. Und das Fenster erstmal noch nicht schliessen. Im Timer kannst du dann prüfen ob der Thread schon terminiert hat. Und wenn er terminiert hat, dann kannst du das Fenster zu machen.
Dabei muss dir aber klar sein dass in der Zeit der User weiterhin auf Buttons klicken kann etc., und auch weiterhin die entsprechenden Handler aufgerufen werden. D.h. zumindest sollte man das Fenster bzw. alle Controls des Fensters deaktivieren.
Oder aber du verzichtest auf Invoke, und verwendest statt dessen einen nicht-blockierenden "Kommunikationskanal" zwischen Worker-Thread und GUI-Thread. Wie eben z.B. BeginInvoke.
-
Guten Morgen,
ahh d.h. meine exit-Handler wird auch in der Message-Loop verarbeitet, die aber durch as While(IsAlive)... blockiert ist, und somit meine ThreadLoop nihc beenden wird, weil er in Dispatcher.Invoke hängt (da diese auch in der MessageLoop) is!?
-
Erkläre bitte noch einmal genau, was du vorhast.
Wenn du die Applikation einschlieslich aller Threads beenden willst, sollte
Application.Exit()
reichen.
-
Ich habe nen Thread zum daten pollen:
Thread Func:
do { ReadDataWithAGLink(); } while (!_manualResetEvent.WaitOne(100));
und um den Thread sauber zu beenden, rufe ich in der Dispse
_manualResetEvent.Set();
auf.
Application.Exit();
wird das nich machen!
-
Schätze mal er will nen kontrollierten, sauberen Shutdown machen?
-
Schätze mal er will nen kontrollierten, sauberen Shutdown machen?
Richtig!
Alles andere is glaub nich soo cool
-
Ich muss das Themad doch nochmal aufmachen;)
Das ganze hier findet ja in einem UserControl stattt...
_thread = new Thread(ThreadFunc); _manualResetEvent = new ManualResetEvent(false); _thread.Start(); .... private void ThreadFunc() { do { ReadDataWithAGLink(); Dispatcher.Invoke(.....); } while (!_manualResetEvent.WaitOne(100)); HIER! } ... public void Dispose() { _manualResetEvent.Set(); while (_thread.IsAlive) Thread.Sleep(100); }
wenn ich das Control zerstöre, also Dipose aufrufe und es dann aus dem VisualTree nehme, dann is das Control ja noch nich zerstört.
Es wird also in while (_thread.IsAlive) gewartet bis das letze mal Dispatcher.Invoke aufgerufen wurde, danach kann das Control "gelöscht" werden.oder blockiert
while (_thread.IsAlive) Thread.Sleep(100);
das den dispatcher?? bei Thread.Sleep(100); kann er doch sein zeugs fertig machen?
oder habe ich ein verständnis problem :p :p
-
ok ich bin wohl doch grün hinter den ohren
http://stackoverflow.com/questions/22158278/wait-some-seconds-without-blocking-ui-execution
-
Ich habe die starke Befürchtung, dass du dir weder die Probleme über die du stolperst, noch die Lösungen die du dazu dann findest, so genau ansiehst, dass du auch verstehst was da eigentlich wirklich passiert.
So hast du zwar kurzfristig den Eindruck schneller voranzukommen, aber in Wirklichkeit lernst du nichts.
-
Ja das kann gut sein hustbear.
Deswegen bin ich hier um von euch zu lernen. Aber das Problem das ich habe, kannst du da vll. was dazussagen:)
-
Hab ich doch schon. Du bist bloss ein wenig lernresistent. Das Problem wegen dem du fragst ist 1:1 das selbe wie im ersten Beitrag. Die Antworten bleiben daher auch 1:1 die selben.