2015-04-21 9 views
8

मैं मेरे सामने इस कोड को देख सकते हैं और मैं संदिग्ध हूँ:क्या कोड है जो रद्द करने के लिए रद्द कर रहा है जबकि कार्य रद्द कर रहे हैं?

CancellationTokenSource _cts; 

public void Dispose(); 
{ 
    _cts.Cancel(); 
    _cts.Dispose(); 
    _task.Wait(); //wait for the task to be canceled!? 
} 

इसे सुरक्षित _cts.Dispose() कॉल करने के लिए सीधे के बाद रद्द है? क्या रद्द करने के लिए रद्द किए जा रहे कार्य के लिए रद्द करने के लिए आवश्यक रद्दीकरण टोकनसोर्स के अंतर्निहित संसाधनों का निपटान नहीं करना चाहिए, अगर ऐसा करना चाहते हैं तो?

उत्तर

7

क्या यह _cts पर कॉल करना सुरक्षित है? रद्द करने के बाद सीधे() का उपयोग करें?

यह जानने के लिए, हमें यह समझने की आवश्यकता है कि जब हम CancellationTokenSource को रद्द करते हैं तो क्या होता है।

जब आप CancellationTokenSource को रद्द करते हैं, तो यह CancellationToken के माध्यम से पंजीकृत किसी भी कॉलबैक का आह्वान करता है, जिसमें CancellationToken.Register() विधि के माध्यम से इसके मूल स्रोत का संदर्भ होता है।

अब, जब आप एक सीटीएस का निपटान करते हैं, तो पंजीकृत किसी भी लिंकिंग कॉलबैक को टोकन से डी-पंजीकृत होने का प्रयास किया जाता है। यदि यह वर्तमान में निष्पादित हो रहा है, तो यह तब तक इंतजार करेगा जब तक कि इसका प्रतिनिधि पूरा नहीं हो जाता है।

जिसका अर्थ है कि यद्यपि आपने अपने सीटीएस का निपटारा किया है, फिर भी ऑब्जेक्ट को टोकन द्वारा संदर्भित किया गया है। इसलिए, यह अभी भी संग्रह के लिए योग्य नहीं है।

अब CancellationToken.IsCancellationRequested को देखो:

public bool IsCancellationRequested 
{ 
    get 
    { 
     return m_source != null && m_source.IsCancellationRequested; 
    } 
} 

इसका मतलब यह है कि जब तक निपटाए रद्द जाँच सही निकलेगा। इसका मतलब यह है कि निपटान के बाद कार्यों को पूरा करने के लिए आपके लिए सुरक्षित है।

एक साइड नोट के रूप में, यदि आप (किसी कारण से) इसके निपटारे रद्द करने के लिए टोकन पास करने का प्रयास करते हैं तो आप ObjectDisposedException दबाएंगे।

संपादित करें:

दो बातें मैं जोड़ना चाहते हैं। सबसे पहले, मुझे यह कहना है कि मैं इस दृष्टिकोण का उपयोग करने की अनुशंसा नहीं करता हूं। इसे कुछ कोड निष्पादन पथों के लिए काम करना चाहिए, लेकिन सभी के लिए नहीं। CancellationTokenSource सामान्यतः तभी निकाला जाना चाहिए यदि आप इसका WaitHandle संपत्ति का उपयोग करते हैं। अन्यथा, सफाई करने के लिए इसे जीसी तक छोड़ना ठीक है। लेकिन, क्योंकि यह स्वाद का विषय है, आप जो भी चाहें चुन सकते हैं। निश्चित रूप से कार्य को रद्द करने के अनुरोध को देखते हुए मैं निश्चित रूप से निपटान करने की सलाह दूंगा।

WaitHandle के उपयोग के अनुसार, इसे निपटाने के बाद इसे निपटान और हटा दिया जाएगा, इसलिए पहुंच योग्य नहीं होगा।

+1

लेकिन IsCancellationRequested सही के बारे में चिंता करने का एकमात्र परिदृश्य नहीं है? WaitHandle के बारे में क्या? रनों का निपटान करते समय –

+0

'वेटहैंडल' बंद हो जाएगा। मुझे यकीन नहीं है कि 'WaitHandle' का उपयोग करना एक आम उपयोग केस है। मैं इसे अपने उत्तर में जोड़ता हूं। –

+0

@Tim मैंने अपने उत्तर में एक महत्वपूर्ण संपादन जोड़ा है। यद्यपि आप जो करने की कोशिश कर रहे हैं वह * संभव * है, मैं निश्चित रूप से इसकी अनुशंसा नहीं करता। –

संबंधित मुद्दे