Wie kann ich erkennen, ein Threadabort in einem finally-Block? (.NETZ)

stimmen
8

Ich habe einige kritische Logik in einem finally-Block (mit einem leeren Try-Block), weil ich, dass der Code garantieren will ausgeführt wird, auch wenn der Thread abgebrochen. Allerdings würde Ich mag auch den Threadabort erkennen. Ich habe festgestellt, dass mein kritischen Versuch Einwickeln / finally-Block in einem try / catch nicht den Threadabort fängt. Gibt es eine Möglichkeit, es zu erkennen?

Versuchen {
    Versuchen { }
    endlich {
        // kritische Logik
    }
} Catch (Exception ex) {
    // Threadabort ist hier nicht gefangen, sondern Ausnahmen geworfen
    // innerhalb der kritischen Logik
}
Veröffentlicht am 09/12/2008 um 17:02
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
2

Lesen Sie mehr über Constrained Execution Regionen .

Insbesondere die RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup Verfahren wird hier nützlich sein.

Beantwortet am 09/12/2008 um 17:04
quelle vom benutzer

stimmen
3

Sie können tatsächlich Code in der catch-Anweisung nur gut für einen Thread auszuführen. Das Problem ist, dass die Ausnahme erneut ausgelöst wird, sobald die Ausführung des catch-Block verlässt.

Wenn Sie die Ausnahme tatsächlich stoppen aus fort können Sie Thread.ResetAbort () aufrufen. Dies gilt allerdings volles Vertrauen erfordern und wenn Sie ein bestimmtes Szenario haben, ist es an Sicherheit grenzender Wahrscheinlichkeit die falsche Sache zu tun.

Threadabort

Beantwortet am 09/12/2008 um 17:07
quelle vom benutzer

stimmen
2

Ich glaube nicht, dass es möglich ist.

Warum müssen Sie die Handhabung Thread in erster Linie? Der Aufruf Thread.Abort () ist in der Regel ein Zeichen für schlechtes Design. Haben Sie einen Flag - Variable , dass , wenn auf true gesetzt wird einfach zurückkehren; von der Fadenfunktion nach entsprechender cleanup natürlich.

Auf diese Weise werden Sie nicht über die Ausnahme kümmern müssen.

Beantwortet am 09/12/2008 um 17:22
quelle vom benutzer

stimmen
0

Ich stimme mit arul. Der Aufruf Thread.Abort () ist ein Zeichen für schlechtes Design.

Lassen Sie mich Peter Ritchie aus zitieren MSDN: Thread.Abort (Schwerpunkt ist von mir):

Es gibt viele Gründe, nicht zu verwenden Thread.Abort und Threadabort

Auf bestimmte Plattformen (wie x64 und IA64) kann der Abbruch erfolgen, bevor Monitor.Enter und einen try-Block (auch mit Schloss / SyncLock), so dass der Monitor verwaiste. Der Threadabort kann in 3rd-Party-Code auftritt nicht geschrieben Thread abbrechen zu handhaben. Verwendet Ausnahmen für die normale Steuerung Ablauflogik das Thread kann abgebrochen werden, während der Verarbeitung ein schließlich in .NET 1.x blockieren. Asynchrone Ausnahme kann Modifikation von Shard Zustand oder Ressourcen unterbrechen, sie beschädigte verlassen.

Weiteres Detail:
http://msmvps.com/blogs/peterritchie/archive/2007/08/22/thead-abort-is-a-sign-of-a-poorly-designed-program.aspx
http: // www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx
http://blogs.msdn.com/ericlippert/archive/2007/08/17/subtleties-of-c-il-codegen.aspx

Beantwortet am 11/12/2008 um 11:43
quelle vom benutzer

stimmen
0

Haben Sie versucht, so etwas wie das?

try {
    try { }
    catch (ThreadAbortException)
    {
      ThreadAbortExceptionBool = true;
    }
    finally {
        // critical logic
        if (ThreadAbortExceptionBool)
          // Whatever
    }
} 
catch(Exception ex) {
    // ThreadAbortException is not caught here, but exceptions thrown
    // from within the critical logic are
}
Beantwortet am 02/03/2009 um 16:15
quelle vom benutzer

stimmen
8

Dies ist ein merkwürdiges Problem.

Der Code , den Sie geschrieben sollten arbeiten. Es scheint , es ist eine Art von Optimierung geht , dass Ihre catch - Handler nicht zu nennen entscheidet.

So wollte ich die Ausnahme mit dieser erkennen:

bool threadAborted = true;
try {
  try { }
  finally { /* critical code */ }
  threadAborted = false;
}
finally {
  Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");

(Mein eigentlicher Code schlief gerade in diesem kritischen Codeabschnitt, so konnte ich sicher sein, es danach abbrechen würde schließlich.)

Es gedruckt:

Faden abgebrochen? Falsch

Hmmm, seltsam in der Tat!

Also dachte ich über ein wenig mehr Arbeit zu tun, alle „intelligenten“ Optimierungen Trick:

bool threadAborted = true;
try {
  try { }
  finally { /* critical code */ }
  threadAborted = AmIEvil();
}
finally {
  Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");

Wo AmIEvilist nur:

[MethodImpl(MethodImplOptions.NoInlining)]
static bool AmIEvil() {
  return false;
}

Endlich ist es gedruckt:

Faden abgebrochen? Wahr

Und dort haben Sie es. Verwenden Sie diese in Ihrem Code:

try {
  try { }
  finally { /* critical code */ }
  NoOp();
}
catch (Exception ex) {
  // ThreadAbortException is caught here now!
}

Wo NoOpist nur:

[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }
Beantwortet am 03/03/2011 um 19:02
quelle vom benutzer

stimmen
2

Wenn Aufruf Thread.Abort ist schlechtes Design warum rufen Sie SQL Server auf einem Thread, der Benutzercode ausgeführt wird? Denn das ist genau, wie eine Abfrage abbrechen behandelt wird und es verursacht Alpträume.

Beantwortet am 18/11/2011 um 22:23
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more