2008-10-21 10 views
5

In meiner App habe ich einen Thread, der für einige Zeit "Bitte warten" Dialogfeld anzeigt, manchmal ist es eine sehr kleine Menge Zeit und es gibt einige Störungen beim Zeichnen UI (ich denke)."Thread wurde abgebrochen" Ausnahme beim Anzeigen des Dialogs

Ich bekomme die Ausnahme "Thread wurde abgebrochen" und habe keine Ahnung, wie es loszuwerden. Ich meine, diese Ausnahme auf irgendeine Weise abfangen oder auf andere Weise vor dem Benutzer verbergen. Diese Ausnahme hat nichts mit dem Rest meiner App zu tun und dieser Fehler hat keinerlei Auswirkungen auf sie. Erscheint zufällig und es ist schwierig, bei einem Anruf neu zu erstellen.

Ich habe auf verschiedene Arten versucht, diese Ausnahme durch Code zu fangen, der Thread mit dem Dialogfenster startet und stoppt, aber es scheint, dass der Fehler anscheinend neben einem anderen Thread liegt, der das Fenster in meinem neu erstellten Thread anzeigt.

Hier ist ein Codebeispiel, Teil der statischen Klasse mit nützlichen Sachen, natürlich sage ich nicht, dass das ein guter Weg ist, um diese Art von "beschäftigt" Situation zu lösen, aber ich möchte dieses Problem lösen. Thread.Sleep (500); oder andere Try/Catch-Verbesserungen helfen mir nicht, diese Thread-Ausnahme zu vermeiden.

public static bool alreadyBusy = false; 
    public static BusyIndicator bi = new BusyIndicator(""); 
    public static Thread backgroundOpertionThread; 

    public static void showBusy(bool isBusy, System.Windows.Forms.Form hostform, string message) 
    { 
     Common.busyMessage = message; 
     if (isBusy) 
     { 
      Common.alreadyBusy = true; 
      backgroundOpertionThread = new Thread(new ThreadStart(showBusy)); 
      Thread.Sleep(500); 
      if (hostform != null) 
      { 
       hostform.Enabled = false; 
       hostform.SuspendLayout(); 
      } 
      backgroundOpertionThread.Start(); 

     } 
     else 
     { 

      backgroundOpertionThread.Abort(); 
      Thread.Sleep(500); 
      Common.alreadyBusy = false; 
      if (hostform != null) 
      { 
       hostform.Enabled = true; 
       hostform.ResumeLayout(); 
      } 
     } 
    } 

    public static void showBusy() 
    { 
     BusyIndicator bir = new BusyIndicator(Common.busyMessage); 
     bir.ShowDialog(); 
    } 

Irgendwelche Ideen?

+0

Können Sie Ihre Frage mit einem Codebeispiel aktualisieren? – jezell

Antwort

15

Do nicht Thread.Abort verwenden. Diese Methode ist reserviert, wenn die .NET-Laufzeit zwangsweise Threads beenden muss, um das Programm zu entladen.

Sie können dies nur "sicher" verwenden, wenn Sie eine Anwendungsdomäne entladen möchten und die darin ausgeführten Threads loswerden möchten.

Um einen Thread loszuwerden, schreiben Sie es im kooperativen Modus. Dies bedeutet, dass der Thread regelmäßig eine Art von Flag überprüfen sollte und wenn das Flag gesetzt ist, normal aus der Thread-Methode austreten. Um den Thread "zu töten", setze einfach die Flagge und warte bis der Thread beendet ist.

Sie können ein Event-Objekt oder eine einfache boolesche Variable für dieses Flag verwenden.

Aber nicht Thread.Abort verwenden.

+2

+1. Und nur zur Betonung: * Benutze Thread.Abort nicht! * :-) –

+2

Der anmutige Thread-Exit-Ansatz ist alles in Ordnung und gut, wenn ein Thread tatsächlich in der Lage ist, den Wert eines Flags kontinuierlich und zuverlässig zu prüfen (zB in einer Schleife) , aber was ist, wenn der Thread eine 'Heavy Lifting'-Aufgabe ausführt und in einer einzigen Codezeile eingeschlossen ist? Thread.Abort() ist die einzige Möglichkeit, einen Thread in einem solchen Szenario zu beenden. Ist ein anderer Weg möglich? – Bosco

+2

Ich würde gerne sehen, Boscos Frage beantwortet, bitte. – jocull

1

Verwendung SafeThread und setzen ShouldReportThreadAbort auf false das Problem weggehen zu machen ...

eine bessere Lösung wäre dies mit Debug >> Ausnahmen im Debugger auszuführen >> für alle Ausnahmetypen geprüft Geworfen und Finde heraus, was passiert, um deinen Thread abzubrechen

EDIT: Danke für das Posten der Codebeispiel, das macht das Problem viel einfacher zu sehen. WÄHLEN SIE NICHT THREAD.ABORT

+0

Das Problem ist, dass so eine Ausnahme schwer wiederherzustellen ist, vor allem in Debug Environment aufgrund von Bit-Verlangsamung auf Operationen, die Debug-Umgebung bietet. Soweit ich mich erinnere Stapel Fehler im GUI Zeichnungs Thread von NET Framework über meinem Code – MoreThanChaos

+0

und natürlich versuche ich, Ihre Ratschläge zu verwenden, aber es wird keine Möglichkeit geben, genaue Tests zu machen, denn wie ich sagte Ausnahme-Faktoren sind schwer neu zu erstellen – MoreThanChaos

0

Vereinbart mit Steven Idee über alle Ausnahmen beim Werfen ausgelöst. Dann können Sie das Problem sofort sehen.

Eine Sache, die Sie nicht vergessen sollten: Sie werden nicht über die Debug-Menüoption verfügen, wenn Ihre Visual Studio-Einstellungen im Gegensatz zur Einstellung "Visual C# Developer" allgemein sind. Fängt mich immer noch auf, wenn ich auf einer neuen Maschine bin oder ein neues Profil verwende ...

+0

bereits auf zwei verschiedenen Maschinen getestet, lesen Sie bitte die Kommentare zur vorherigen Antwort – MoreThanChaos

-3

können Sie versuchen,

Aufruf
Thread.Sleep(500); 

nach

backgroundOpertionThread.Start(); 

Dies würde der Hintergrund-Thread 500 ms geben zu tun, was es tun muss, bevor der Haupt-Thread eine Chance bekommt

anrufen
backgroundOpertionThread.Abort(); 

Edit: Aber ich stimme zu, dass die beste Lösung wäre, Thread.Abort() überhaupt nicht zu verwenden

Verwandte Themen