Nasıl bir bir ThreadAbortException nihayet engellemek algılayabilir? (.AĞ)

oy
8

Ben kod parçacığı iptal olsa bile işletilirse garanti etmek istiyorum, çünkü ben, (boş bir try'ın ile) nihayet bloğunda bazı kritik mantığı var. Ancak, ben de ThreadAbortException algılamak istiyorum. Benim kritik deneyin sarma / nihayet ThreadAbortException yakalamak vermeyen bir try / catch blok saptadık. bunu tespit için herhangi bir yolu var mı?

Deneyin {
    Deneyin { }
    en sonunda {
        // kritik mantık
    }
} Catch (Exception ex) {
    // ThreadAbortException burada yakalanmış, ancak istisnalar atılmış değil
    Kritik mantığı içinden edilir //
}
Oluştur 09/12/2008 saat 17:02
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
8

Bu meraklı bir sorundur.

Yayınladığınız kod gerekir çalışır. O senin yakalamak yöneticisini çağırmak için karar verir oluyor optimizasyon bir tür sorun var gibi görünüyor.

Yani, bu ile istisna algılamak istedim:

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

(Benim gerçek kod sadece o kritik kod bölümünde uyudu, bu yüzden nihayet bundan sonra iptal olur emin olabilir.)

Bu baskılı:

iptal Konu |? Yanlış

Hmmm, aslında garip!

Bu yüzden herhangi bir "akıllı" optimizasyonlar kandırmak için, orada biraz daha fazla çalışma yapmayı düşündü:

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

Nerede AmIEviladildir:

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

Son olarak, baskılı:

iptal Konu |? Doğru

İşte buyur. kodunuzda bunu kullanın:

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

Nerede NoOpadildir:

[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }
Cevap 03/03/2011 saat 19:02
kaynak kullanıcı

oy
3

Aslında bir ThreadAbortException için sadece iyi yakalamak açıklamada kodu çalıştırabilirsiniz. Sorun yürütme catch bloğu çıkıncadüzelecektir istisna rethrown edilecektir olmasıdır.

aslında sen () Thread.ResetAbort çağırabilir devam etmesini istisna durdurmak istiyorsanız. Gerçi tam güven gerektirir ve belirli bir senaryo olmadığı sürece, bunu yapmak için yanlış bir şey neredeyse kesin.

ThreadAbortException

Cevap 09/12/2008 saat 17:07
kaynak kullanıcı

oy
2

çağıran Thread.Abort kötü tasarım ise neden SQL Server kullanıcı kodu çalıştıran bir iş parçacığı üzerinde sesleniyor? Bu sorgu iptal ele alınır ve kabus neden tam olarak nasıl olduğu için.

Cevap 18/11/2011 saat 22:23
kaynak kullanıcı

oy
2

Bunun mümkün olduğunu sanmıyorum.

Neden işlemek gerekiyor ThreadAbortException ilk etapta? Arayan Thread.Abort () genellikle kötü tasarım bir işaretidir. True değerine ayarlandığında basitçe olacağı bir bayrak değişkeni var return; İplik işlevinden, elbette uygun temizleme sonra.

Bu yolla istisna konusunda endişelenmenize gerek kalmaz.

Cevap 09/12/2008 saat 17:22
kaynak kullanıcı

oy
2

Hakkında okuyun Kısıtlı Yürütme Bölgeler .

Özellikle, RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup yöntemi burada faydalı olacaktır.

Cevap 09/12/2008 saat 17:04
kaynak kullanıcı

oy
0

Böyle bir şey denediniz mi?

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
}
Cevap 02/03/2009 saat 16:15
kaynak kullanıcı

oy
0

Ben Arul katılıyorum. Arayan Thread.Abort () kötü tasarım bir işaretidir.

Bana Peter Ritchie aktaralım Thread.Abort: MSDN (vurgu bana ait):

Thread.Abort ve ThreadAbortException kullanmamaya birçok nedeni var

(X64 ve IA64 gibi) belli platformlarda iptal yetim monitörü bırakarak Monitor.Enter ve (hatta kilit / SyncLock ile) Try bloğundan önce ortaya çıkabilir. ThreadAbortException iplik iptaline işlemek için yazılmamış 3. parti kodunda meydana gelebilir. Bir nihayet .NET 1.x normal kontrol akış mantığı için istisnalar kullanır bloke işlerken iplik iptal edilebilir. Asenkron istisna bozuk bırakarak, shard devlet veya kaynakların modifikasyonunu kesebilir.

Daha fazla ayrıntı için bkz:
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

Cevap 11/12/2008 saat 11:43
kaynak kullanıcı

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