5 Stimmen

Wie unterdrücke ich einen thread.abort() Fehler C#?

Ich zeige einen Splash-Screen in einem Hintergrund-Thread an, während mein Programm geladen wird. Sobald das Programm geladen ist, breche ich den Thread ab, da es der einzige Zweck war, ein "Now Loading"-Splash-Formular anzuzeigen.

Mein Problem ist, dass beim Abbrechen eines Threads ein ThreadAbortException auf die der Benutzer einfach weiter klicken kann.

Wie kann ich damit umgehen? Ich habe versucht, es so zu unterdrücken -->

            try
        {
            Program.splashThread.Abort();
        }
        catch(Exception ex)
        {

        }

aber ich habe das Gefühl, dass man mich hier anschreien wird, und das funktioniert so oder so nicht.

Gracias.

4 Stimmen

Ich habe erst kürzlich einen Blog über die Erstellung eines Startbildschirms geschrieben. Mal sehen, ob Ihnen das weiterhilft: crazorsharp.blogspot.com/2009/06/ </self_promotion>

2 Stimmen

Wenn Sie Thread.Abort verwenden müssen, machen Sie (im Allgemeinen) etwas falsch. Versuchen Sie, einen anderen, sichereren Weg zu finden. Viele gute Vorschläge unten.

1 Stimmen

@BFree: Wenn ich könnte, würde ich Sie an der Antwort teilhaben lassen! Danke für das konstruktive Feedback. Ich lerne schon so viel von Ihrem Beitrag! Während die andere Antwort meine aktuelle Lösung zum Funktionieren gebracht hat, erwarte ich, dass ich ein robusteres Splash aus den Informationen in Ihrem Blog erstellen werde. Ich danke Ihnen!

20voto

Fredrik Mörk Punkte 151006

Sie brauchen den Thread nicht zu löschen. Ich werde es mit einem Code veranschaulichen.

Im Formular für den Begrüßungsbildschirm:

public void CloseSplash()
{
    Invoke((MethodInvoker)delegate
    {
        this.Close();
    });
}

In der Datei Program.cs:

private static Splash _splash = null;
public static void CloseSplash()
{
    if (_splash!= null)
    {
        _splash.CloseSplash();
    }
}

Wenn Ihre Main-Methode startet, zeigen Sie den Splash in einem Thread an:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
    _splash.ShowDialog();
}));

t.Start();

...und wenn Sie es schließen wollen, schließen Sie es einfach:

Program.CloseSplash();

Dann brauchen Sie sich nicht um den Abbruch des Threads zu kümmern; er wird ordnungsgemäß beendet.

2 Stimmen

Danke, dass Sie mir gezeigt haben, wie ich das besser machen kann. Ich schätze Ihr konstruktives Feedback sehr!

9voto

CodeWarrior Punkte 337

Bitte beachten Sie den folgenden Link, den Sie über eine Google-Suche erhalten (erstes Ergebnis):

http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx

Achten Sie besonders auf diesen Teil:

Wenn diese Methode auf einem Thread aufgerufen wird, löst das System eine ThreadAbortException im Thread, um ihn abzubrechen. ThreadAbortException ist eine spezielle Ausnahme, die von Anwendungscode abgefangen werden kann, aber am Ende des Catch-Blocks wieder verworfen wird, es sei denn ResetAbort genannt wird. ResetAbort bricht die Aufforderung zum Abbruch ab und verhindert, dass die ThreadAbortException von der Beendigung des Threads ab. Nicht ausgeführte finally-Blöcke werden ausgeführt, bevor der Thread abgebrochen wird.

0 Stimmen

Ich wollte dies gerade veröffentlichen. Mit anderen Worten: Was er tun will, ist wahrscheinlich unmöglich.

7voto

Die Verwendung von Threadabort wird nicht empfohlen. Es ist böse. Warum nicht einen anderen Mechanismus wie ein (Auto/Manual)ResetEvent verwenden? Starten Sie den Thread mit dem Splash-Screen, warten Sie auf das Ereignis. Wenn der andere Code mit dem Laden fertig ist, setzen Sie das Ereignis und erlauben Sie dem Splash-Screen, sich auf die normale (nette) Weise zu schließen.

0 Stimmen

Nimmt mir die Worte direkt aus dem Mund ;-) Ich wollte sogar schreiben, dass Thread.Abort() böse ist, haha.

4voto

Alan Jackson Punkte 6093

Ändern Sie den Ausnahmetyp in ThreadAbortException und fügen Sie einen Aufruf an ResetAbort()

    try
    {
        Program.splashThread.Abort();
    }
    catch(ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }

Das Abbrechen von Threads wird im Allgemeinen als sehr schlechte Praxis angesehen und kann zu allen möglichen schwer aufzuspürenden Fehlern führen. Haben Sie in Erwägung gezogen, einen Weg zu finden, einfach Schließen Sie das Splash-Fenster oder verwenden Sie eine Art von Abfrage um den Thread zu stoppen, wenn ein Flag gesetzt wurde?

0 Stimmen

Wenn ich das Splash-Formular schließe und das ist ALLES, was der Thread gemacht hat, wird dann mein Thread aufgelöst?

4voto

bobbyalex Punkte 2623

Einige Punkte. Die ThreadAbort-Ausnahme ist der Grund für den Abbruch des Threads. Sie ist kein Nebeneffekt des Aufrufs von abort. Wenn Sie einen Thread abortieren, erzwingt die Laufzeit eine ThreadAbort-Ausnahme, die an den Thread weitergegeben wird. Diese Ausnahme kann abgefangen werden, da sie es dem Benutzer ermöglicht, einige Bereinigungen durchzuführen, bevor der Thread abbricht.

Die Ausnahme wird dann automatisch erneut ausgelöst, um sicherzustellen, dass der Thread abgebrochen wird. Wenn die Ausnahme abgefangen und nicht erneut ausgelöst wird, wird der Thread nie abgebrochen.

Eigentlich ein intelligentes Design.

Es ist also völlig in Ordnung, diese Ausnahme abzufangen. Das sollten Sie sogar. Aber fangen Sie nur diese spezielle Ausnahme ab und nicht die allgemeine Ausnahme. (wie unten gezeigt)

catch(ThreadAbortException ex)
{
   //This is an expected exception. The thread is being aborted
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X