Boş bir deneme bloğuyla neden {} sonunda {} deneyin?


239

System.Threading.TimerBase.Dispose()Yöntemde bir try{} finally{}blok olduğunu fark ettim ama try{}boş.

try{} finally{}Boş ile kullanımda herhangi bir değer var mı try?

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
    bool status = false;
    bool bLockTaken = false;
    RuntimeHelpers.PrepareConstrainedRegions();
    try {
    }
    finally {
        do {
            if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
                bLockTaken = true;
                try {
                    status = DeleteTimerNative(notifyObject.SafeWaitHandle);
                }
                finally {
                    m_lock = 0;
                }
            }
            Thread.SpinWait(1);
            // yield to processor
        }
        while (!bLockTaken);
        GC.SuppressFinalize(this);
    }

    return status;
}

System.Diagnostics. 2144 hattı çevresinde de işlem yapın: referenceource.microsoft.com/#System/services/monitoring/…
Patrick Artner

Yanıtlar:


171

Gönderen http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/ :

Bu metodoloji, işlemi kesintiye uğratan bir Thread.Abort çağrısına karşı koruma sağlar. Thread.Abort'un MSDN sayfası “İş parçacığı iptal edilmeden önce beklenmedik şekilde bloklar yürütüldüğünü” söylüyor. Bu nedenle, iş parçacığınızın iş parçacığınızda iptal etmesini isteyen bir kişi tarafından ortada iptal edilmiş olsa bile işleminizin tamamlanmasını garanti etmek için, tüm kodunuzu nihayet bloğa yerleştirebilirsiniz (alternatif, "catch" bloğuna kod yazmaktır. “den” işleminin Abort tarafından kesilmeden önce nerede olduğunuzu belirleyin ve isterseniz oradan devam edin).



15
Çünkü bu .NET 2.0'a kadar mevcut değildi
Hans Passant

6
RobFonseca-Ensor @: Çünkü Thread.BeginCriticalRegion()vermez önlemek iptal edilmesini bir iplik yerine o çalışma zamanını söyler eğer bir iş parçacığı iptal edilir, daha sonra küresel devlet bozuk ve bütün AppDomain bir rahmet öldürme kalmıştır.
kkm

9
@HansPassant: BeginCriticalSection()gerçekten .NET 1.x orada değildi, ama hiçbir neden ve sonuç size söyleyerek ima olduğunu, orada çünkü . Aslında, .NET 1.x'te, bir finallyblok bile bir iş parçacığı iptali tarafından kesilmiş olabilir. Bu mekanizmalar farklı bir amaca hizmet eder: çalışma finallyzamanına BeginCriticalSection()yalnızca küresel durumun risk altında olduğunu bildirirken kodun ortasında iptal edilmesini önler .
kkm

Geliştiricinin nihayetinde bir süre (true) varsa, kürtaj tamamlanmış olur mu veya bir kürtaj teknik olarak süresiz olarak göz ardı edilebilir mi?
Max Young

64

Bu, Thread.Abortbir süreci kesintiye uğratmaya karşı korumak içindir . Bu yöntemin belgeleri şöyle diyor:

Beklenmeyen sonunda blok iş parçacığı durdurulmadan önce yürütülür.

Bunun nedeni, bir hatadan başarıyla kurtulmak için kodunuzun kendisinden sonra temizlenmesi gerekir. C #, C ++ tarzı yıkıcılara sahip olmadığından finallyve usingbloklar, bu tür temizlemenin güvenilir bir şekilde gerçekleştirilmesini sağlamanın tek güvenilir yoludur. Bu usingbloğun derleyici tarafından buna dönüştüğünü unutmayın :

try {
    ...
}
finally {
    if(obj != null)
        ((IDisposable)obj).Dispose();
}

.NET 1.x'te, finallybloğun durdurulması ihtimali vardı . Bu davranış, .NET 2.0'da değiştirildi.

Dahası, boş trybloklar derleyici tarafından asla optimize edilmez.


Kullanım bloğundaki içgörü için teşekkürler.
Stefan

@Anton kullanmanın en iyi uygulama olduğunu anlıyorum. Ancak alaycı amaçlar için bazen bir sarıcı sınıfın uygulanması gerekir ve tek kullanımlık nesne özel bir sınıf değişkeni haline gelir. Bu sargıyı tek kullanımlık yaparsak, GC özel sınıf değişkeninin atılmasını otomatik olarak yapmıyor mu?
Ozkan

@ Özkan GC hiçbir şeyi otomatik olarak atmaz. Tipik olarak bir çağıran bir sonlandırıcı uygulamanız gerekir Dispose(false);. docs.microsoft.com/tr-tr/dotnet/standard/garbage-collection/…
Thorarin

@Trararin üzgünüm ama GC'nin otomatik olarak atmadığını (sonlandırdığını) söyleyerek yanılıyorsunuz.
Ozkan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.