2009-03-25 3 views
1

Ich habe ein Programm, das den Quellcode analysiert. Es kann rekursiv durch ein Verzeichnis gehen, um alle Projekte zu finden, und dann rekursiv durch das Projekt gehen, um den gesamten Quellcode zu finden.Erstellen eines Stornierungsschemas

Ich möchte eine Schaltfläche zum Abbrechen des Prozesses erstellen, die es dem Benutzer ermöglicht, die Codeanalyse zu stoppen. Ich führe die Code-Analyse in einem Hintergrund-Worker aus. Ich möchte in der Lage sein, auf das Absage-Ereignis zu achten.

Das Problem ist herauszufinden, wie Sie meinen Code bearbeiten, so dass es gehen und überprüfen Sie das Element und zurück zur GUI zurückkehren. Der Analyseprozess geht mehrere Methoden tief.

In einem viel kleineren Prozess verwende ich erfolgreich ein threadsicheres Singleton mit einem Bool, das angibt, ob ein Abbruch angefordert wurde oder nicht, und die Schleife dort anhalten, wo sie ausgeführt wird.

Was wäre der beste Weg, um diese Anfrage in meinen Code zu bearbeiten?

EDIT: Hier ist eine Idee, inspiriert von John Saunders 'Antwort.

Was passiert, wenn ich einen Hintergrund-Thread in meinem Verarbeitungsthread ausführen, der auf die Änderung von Singleton Cancel achtet und dann eine Ausnahme von diesem Prozess auslöst? Scheint dies eine gute Praxis? Dies funktioniert nicht wie vorgesehen

EDIT 2: John Saunders 'Antwort scheint die beste für jetzt zu sein. Ich werde nur meine eigene Ausnahme werfen, wenn der Singleton für jetzt wahr ist. Ich werde warten, um zu sehen, ob andere Lösungen vorgeschlagen werden

Antwort

2

Thread.Abort ist eine schlechte Idee, da es den Thread an einem beliebigen Punkt unterbricht - wahrscheinlich unterbricht es, wo Sie am wenigsten unterbrochen werden möchten.

Legen Sie eine Markierung fest, die vom Thread angezeigt wird, der abgebrochen wird. Überprüfen Sie es zu Beginn jeder Operation. Die Idee wäre, Orte im Code zu identifizieren, an denen es sicher ist, sie anzuhalten, und die Flagge nur an diesen Punkten zu überprüfen.

Es kann nützlich sein, an diesen Stellen eine Ausnahme auszulösen. Die Ausnahme sollte eine sein, die nicht von Ihrem Code abgefangen wird, bis sie die Grenze zwischen Ihrem Code und der Benutzeroberfläche erreicht. An diesem Punkt würde Ihr Code einfach zurückkehren.

+0

Ich habe nicht einmal gedacht, eine Ausnahme zu werfen! –

+0

Ausnahmen und mehrere Threads sind ein Problem in den Hintern zu debuggen --- im Allgemeinen: Vorsicht. Der Debugger + mehrere Threads = nicht dein Freund. –

+0

Ich habe darüber gesprochen, die Ausnahme in seinen eigenen Thread zu werfen. Es würde an der Grenze gefangen werden und nicht entkommen. Beachten Sie, dass dies teilweise was Thread.Abort tut (es wirft ThreadAbortException, denke ich). Aber auf diese Weise wird es nur geworfen, wenn es sicher ist. –

0

Sie könnten die Thread.Abort() Funktion auf Ihrem Hintergrund-Worker-Thread verwenden. Dies wirft eine ThreadAbortException, die Sie in jeder Ihrer Methoden fangen können, die aber am Ende der catch Blöcke atomar erneut ausgelöst werden.

Auch alle finally-Bausteine ​​werden ausgeführt.

0

Es hört sich an, als ob Sie die .NET-Klasse von Backgroundworker verwenden. Ich denke, dass Sie einen Objektparameter in der RunWorkerAsync-Methode übergeben können, die dann für den Hintergrundthread in dem DoWork-Ereignishandlerargument zugänglich wird.

Sie könnten dieses Objekt dann im UI-Thread ändern (z. B. eine boolesche Cancel-Eigenschaft aktualisieren) und es regelmäßig von Ihrem Hintergrundprozess aus überprüfen.

0

Es gibt verschiedene Möglichkeiten zum Abbrechen von Thread-Vorgängen; die alle die periodische Überprüfung eines Flags oder eines anderen Wertes beinhalten, um zu bestimmen, ob der Thread weiter arbeiten soll oder nicht.

Ich würde nicht empfehlen Ausnahmen für diese Funktion zu werfen.Zunächst einmal ist die Stornierung kein außergewöhnlicher Umstand, und zweitens ist es zu viel für das, was Sie implementieren möchten.

Stattdessen können Sie ein einfaches threadsicheres boolesches Flag als statisches Member einer Klasse verwenden, auf die von einem beliebigen Thread aus zugegriffen werden kann, oder ein Synchronisationsobjekt wie beispielsweise Mutex verwenden. Durch die Signalisierung des Synchronisationsobjekts würde der Thread dann wissen, dass er abbrechen muss.