Programmabsturz nach Threadabbruch
-
Hallo,
in einem Programm kann ich über einen Scripter, der mittels CodeDom implementiert ist,Funktionen aus unterschiedlichen dlls aufrufen. Nun habe ich ein Stop-Button eingebaut, mit dem man die Möglichkeit haben soll das Script einfach abzubrechen.
Dazu packt man die ganze Scriptausführung ja am besten in einen Thread und kann bei bedarf einfach den Thread abbrechen.
Nun kommt es manches Mal zu programmabstürzen wenn man die Scriptausführung beendet und die Frage ist woran das liegen kann?Im Script werden u.a. Dateien von der Festplatte eingelesen, kann es sein, dass wenn man gerade dann den Thread beenden will, wenn ein Dateilesezugriff stattfindet, es zum Programmabsturz kommen kann?
Viele Grüße
Cain
-
Wie brichst Du dein Script ab?
Wie stopst Du den Thread?Ich hoffe nicht mit Abort(..)...
Simon
-
DeckCain schrieb:
Dazu packt man die ganze Scriptausführung ja am besten in einen Thread und kann bei bedarf einfach den Thread abbrechen.
Nee... wenn dann in eine eigene AppDomain. Aber das geht auch nur, wenn reiner .NET-Code ausgeführt wird!
Thread kann man nicht sicher abbrechen... geschweige denn beenden.
-
Naja wenn man einen Thread schon nicht sicher beenden oder abbrechen kann, dann muss man versuchen einen sicheren Zustand herzustellen, bevor man beendet...
Gibt es eine Möglichkeit zu prüfen ob momentan ein Lese- oder Schreibzugriff auf eine Datei erfolgt?
Wenn man diese Information hätte, könnte man ja solange mit dem Abbruch warten bis der Zugriff beendet wurde...
-
Naja wenn man einen Thread schon nicht sicher beenden oder abbrechen kann,
Ein Thread kann und muss sogar sicher beendet werden. Nur ist eben Abort(..) und ähnliche Methoden nicht sicher. Dein Thread muss immer wieder die Chance kriegen, sich selbst zu beenden, indem er die Thread Funktion verlässt. Dies ist vielleicht gar nicht möglich bei deinem Problem... aber vielleicht ja doch, je nachdem, wie dein Scripting Zeugs impl. ist.
Hier ein Bsp. mit einem ManualResetEvent.
(Ist nur statisch, weil alles in Programm ist...).using System; using System.Threading; namespace Test { class Program { static ManualResetEvent stopThread = new ManualResetEvent(false); static void ThreadFunction() { while ( ! stopThread.WaitOne(0)) { Console.WriteLine(" ... working up the scipt (line by line)..."); Thread.Sleep(1000); } } static void Main(string[] args) { Thread thread = new Thread(new ThreadStart(ThreadFunction)); thread.Start(); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); stopThread.Set(); thread.Join(); stopThread.Close(); } } }
-
Hi theta,
Vielen Dank für Deinen Vorschlag aber ich denke er ist in meinem Fall keine Option weil mit der Joint-Methode wird ja so lange auf den Thread gewartet bis er komplett durchgelaufen ist, dann bräuchte ich ja nicht mal nen Stop-Button, wenn nach dem Klick trotzdem das Script bis zum Ende läuft...
Im Script selber prüfe ich auch immer vor der nächsten aufzurufenden Funktion ob vorher ein Fehler aufgetreten istFehlerNr=Robot.MoveToPos(Robo.X,Robo.Y,200,-180,0,+180,"O"); if(FehlerNr!=0) { MessageBox.Show("FehlerNr: "+Convert.ToString(FehlerNr)); throw new InvalidProgramException(); }
von daher ist der Programmabsturz beim Klick auf den Stop-Button schon so extrem, das nicht mal mehr der catch-Block erreicht wird sondern einfach das gesamte Programm abstürzt...
-
DeckCain schrieb:
Vielen Dank für Deinen Vorschlag aber ich denke er ist in meinem Fall keine Option weil mit der Joint-Methode wird ja so lange auf den Thread gewartet bis er komplett durchgelaufen ist, dann bräuchte ich ja nicht mal nen Stop-Button, wenn nach dem Klick trotzdem das Script bis zum Ende läuft...
ich glaube Du hast das Beispiel nicht richtig gelesen / verstanden...
Der Thread *beendet* sich ja kontrolliert! Deshlab kann man ja das Join machen!
-
Also ich habe es einfach mal ausprobiert, so wie du es vorgeschlagen hast und dabei komme ich beim Debuggen an der Stelle
thread.Join();
nicht weiter(bleibt hängen), wahrscheinlich wartet der aus dem Hauptthread aufgerufene Thread "thread" auf den Hauptthread und der Hauptthread wartet hingegen darauf das der Thread fertig wird?!
Das ganze sieht so aus:
void RunScript() { B_RunScript.Enabled = false; compileThread = new Thread(new ThreadStart(this.compile)); compileThread.Start(); } void StopScript() { stopThread.Set(); compileThread.Join(); stopThread.Close(); EnableStartButton(); }
Ist da irgendwas nicht korrekt?
-
nicht weiter(bleibt hängen), wahrscheinlich wartet der aus dem Hauptthread aufgerufene Thread "thread" auf den Hauptthread und der Hauptthread wartet hingegen darauf das der Thread fertig wird?!
Nein. Nur der aufrufende Thread (der der join() aufruft), wartet auf den anderen Thread.
Ist da irgendwas nicht korrekt?
Das wesentliche sieht man nicht. Nämlich ob Du in compile(..) irgendwo das Event abfragst.
Simon
-
Welches Event meinst du denn? Hat das was mit dem ManualResetEvent zu tun? Habe das bis gerade nicht gekannt...
-
DeckCain schrieb:
Welches Event meinst du denn? Hat das was mit dem ManualResetEvent zu tun? Habe das bis gerade nicht gekannt...
Ja, das ist eben das Problem.
Simon
-
Ich beschäftige mich eben noch nicht so lange mit .NET aber vielen Dank für Deine Bestätigung
-
DeckCain schrieb:
Ich beschäftige mich eben noch nicht so lange mit .NET aber vielen Dank für Deine Bestätigung
Das hat eben auch nicht viel mit .NET im Speziellen zu tun.
Simon