खाली प्रयास ब्लॉक के साथ {} अंततः {} का उपयोग क्यों करें?


239

मैंने देखा System.Threading.TimerBase.Dispose()कि विधि में एक try{} finally{}ब्लॉक है लेकिन try{}खाली है।

क्या try{} finally{}खाली के साथ उपयोग करने में कोई मूल्य है 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.Process लाइन 2144 के आसपास भी: referenceource.microsoft.com/#System/services/monitoring/…
पैट्रिक आर्टनर

जवाबों:


171

से http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/ :

यह कार्यप्रणाली थ्रेड के खिलाफ गार्ड करती है। प्रोसेसिंग में बाधा डालने वाली कॉल। थ्रेड के MSDN पेज। एबॉर्ट का कहना है कि "थ्रेड के निरस्त होने से पहले अंत में ब्लॉक किए गए निष्पादन को निष्पादित किया जाता है"। इसलिए यह सुनिश्चित करने के लिए कि आपका प्रसंस्करण समाप्त हो जाता है, भले ही आपके धागे को बीच में किसी ने अपने धागे पर गर्भपात कर दिया हो, आप अपने सभी कोड को अंत में ब्लॉक में रख सकते हैं (विकल्प "पकड़" ब्लॉक में कोड लिखने के लिए है। निर्धारित करें कि आप "प्रयास" से पहले कहां थे, एबॉर्ट द्वारा बाधित किया गया था और यदि आप चाहते हैं तो वहां से आगे बढ़ें।


6
Msdn.microsoft.com/en-us/library/… का उपयोग क्यों नहीं करते ?
रोब फोंसेका-एंसर

15
क्योंकि .NET 2.0
हंस पैसेंट

6
@ RobFonseca-Ensor: क्योंकि एक थ्रेड को गर्भपात होने से Thread.BeginCriticalRegion()नहीं रोकता है, बल्कि रनटाइम को बताता है कि यदि एक थ्रेड का गर्भपात हो जाता है, तो वैश्विक स्थिति भ्रष्ट है, और पूरे अपडोमेन एक दया हत्या तक है।
किमी 15

9
@ हंसपसंद: BeginCriticalSection()वास्तव में .NET 1.x में नहीं था, लेकिन इसका कोई कारण और प्रभाव नहीं है, क्योंकि आप ऐसा कहने के कारण हैं । वास्तव में, .NET 1.x में, यहां तक ​​कि एक finallyब्लॉक को थ्रेड एबॉर्ट द्वारा बाधित किया जा सकता था। ये तंत्र एक अलग उद्देश्य की पूर्ति करते हैं: finallyकोड में मध्य मार्ग को रोकने वाले कार्य को करना , जबकि BeginCriticalSection()केवल इस बात की घोषणा करता है कि वैश्विक स्थिति खतरे में है।
किमी 19

यदि डेवलपर के पास कुछ समय (सत्य) है, तो अंत में गर्भपात कभी पूरा होगा या तकनीकी रूप से गर्भपात को अनिश्चित काल तक अनदेखा किया जा सकता है?
मैक्स यंग

64

यह Thread.Abortएक प्रक्रिया को बाधित करने से बचाने के लिए है। इस पद्धति के लिए प्रलेखन का कहना है कि:

धागे के निरस्त होने से पहले अंत में ब्लॉक किए गए निष्पादित किए जाते हैं।

ऐसा इसलिए है क्योंकि किसी त्रुटि से सफलतापूर्वक पुनर्प्राप्त करने के लिए, आपके कोड को स्वयं के बाद साफ करना होगा। चूंकि C # में C ++ - स्टाइल डिस्ट्रक्टर्स नहीं हैं, finallyऔर usingब्लॉक यह सुनिश्चित करने का एकमात्र विश्वसनीय तरीका है कि इस तरह के क्लीनअप को विश्वसनीय तरीके से किया जाता है। याद रखें कि usingकंपाइलर द्वारा ब्लॉक इस में बदल जाता है:

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

.NET 1.x में, एक मौका था कि finallyब्लॉक निरस्त हो जाएगा। इस व्यवहार को .NET 2.0 में बदल दिया गया था।

इसके अलावा, खाली tryब्लॉकों को कंपाइलर द्वारा कभी भी अनुकूलित नहीं किया जाता है।


उपयोग ब्लॉक पर अंतर्दृष्टि के लिए धन्यवाद।
स्टीफन

@ एटन मैं समझता हूं कि प्रयोग करना एक सर्वोत्तम अभ्यास है। लेकिन नकली उद्देश्यों के लिए, कभी-कभी एक आवरण वर्ग को लागू करने की आवश्यकता होती है और डिस्पोजेबल ऑब्जेक्ट एक निजी वर्ग चर बन जाता है। अगर हम इस रैपर को डिस्पोजेबल बनाते हैं, तो क्या जीसी निजी वर्ग चर के निपटान को स्वचालित रूप से नहीं कर रहा है?
ओजकान

@ ऑककन जीसी अपने आप कुछ भी डिस्पोज नहीं करता है। आपको अंतिम रूप से लागू करने की आवश्यकता होगी, आम तौर पर कॉलिंग ए Dispose(false);docs.microsoft.com/en-us/dotnet/standard/garbage-collection/...
Thorarin

@ थोरारिन क्षमा करें, लेकिन आप गलत कह रहे हैं कि जीसी स्वचालित रूप से निपटाना (अंतिम रूप देना) नहीं है।
ओजकॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.