रद्द करने के लिए डिफ़ॉल्ट पैरामीटर


96

मेरे पास कुछ async कोड हैं जिन्हें मैं जोड़ना चाहूंगा CancellationToken। हालाँकि, ऐसे कई कार्यान्वयन हैं जहाँ इसकी आवश्यकता नहीं है इसलिए मैं एक डिफ़ॉल्ट पैरामीटर रखना चाहूंगा - शायद CancellationToken.None। तथापि,

Task<x> DoStuff(...., CancellationToken ct = null)

पैदावार

प्रकार का मान '' डिफ़ॉल्ट पैरामीटर के रूप में उपयोग नहीं किया जा सकता है क्योंकि 'System.Threading.CancellationToken' टाइप करने के लिए कोई मानक रूपांतरण नहीं हैं

तथा

Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None)

'Ct' के लिए डिफ़ॉल्ट पैरामीटर मान एक संकलन-समय स्थिर होना चाहिए

क्या इसके लिए कोई डिफ़ॉल्ट मान है CancellationToken?

जवाबों:


151

यह पता चला है कि निम्नलिखित काम करता है:

Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken))

दस्तावेज़ीकरण के अनुसार , जिसकी व्याख्या की जाती है CancellationToken.None:

default(CancellationToken)खाली रद्दीकरण टोकन बनाने के लिए आप C # स्टेटमेंट का भी उपयोग कर सकते हैं ।


4
यह वास्तव में क्या है ढांचे वर्तमान में करता है आंतरिक रूप से, लेकिन मैं होता नहीं मेरी कोड में करते हैं। सोचें कि यदि Microsoft ने अपना कार्यान्वयन बदल दिया और आपके पास CancellationToken.Noneकुछ अधिक हो गया तो आपके कोड के साथ क्या होगा default(CancellationToken)
noseratio

10
@ नोसेराटियो एक बड़े तरीके से पीछे की संगतता को तोड़ देगा, इसलिए मैं ऐसा होने की उम्मीद नहीं करूंगा। और क्या करेगा default(CancellationToken)?
स्विक

3
@ नोट: आप बहुत कठोर हो रहे हैं। संभावना है कि CancellationToken.Noneवास्तव में पदावनत हो जाएंगे। यहां तक ​​कि Microsoft default(CancellationToken)इसके बजाय उपयोग कर रहा है । उदाहरण के लिए, इन खोज परिणामों को इकाई ढांचे के स्रोत कोड से देखें।
ड्रॉ

21
MSDN रद्दीकरण Token.None प्रॉपर्टी से : "आप एक खाली रद्दीकरण टोकन बनाने के लिए C # default (कैनसेलेशनटोकन) स्टेटमेंट का भी उपयोग कर सकते हैं" । कोई भी गलती नहीं है जब तक कि सी # का एक भविष्य संस्करण डिफ़ॉल्ट पैरामीटर के रूप में स्वीकार न करें।
मुईबिएन कर्लोटा

5
यहाँ समान है दो गुम हुए मध्यवर्ती संयोजनों की भरपाई करने के लिए, डेवलपर्स कोई भी या कोई डिफ़ॉल्ट रद्द नहीं कर सकता है रद्द करने के लिए रद्द करें। टोकन पैरामीटर और प्रगति पैरामीटर के लिए शून्य।
एर बाल

25

क्या कैंसलेशनेशन के लिए डिफ़ॉल्ट मान रखने का कोई तरीका है?

दुर्भाग्य से, यह संभव नहीं है, जैसा CancellationToken.Noneकि एक संकलन समय स्थिर नहीं है, जो कि वैकल्पिक तर्कों में डिफ़ॉल्ट मानों के लिए एक आवश्यकता है।

आप एक ही प्रभाव प्रदान कर सकते हैं, हालांकि, डिफ़ॉल्ट मापदंडों का उपयोग करने के बजाय एक अतिभारित विधि बनाकर:

Task<x> DoStuff(...., CancellationToken ct)
{
    //...
}

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}

6
इसे संभालने के लिए यह अनुशंसित तरीका है, जैसा कि MSDN पर टास्क-आधारित एसिंक्रोनस पैटर्न प्रलेखन पर विशेष रूप से समझाया गया है (विशेष रूप से प्रदान करने के लिए अधिभार चुनना अनुभाग में )।
सैम हैरवेल


5
क्या बात है साथ CancellationToken cancellationToken = default(CancellationToken)? यहाँ भी वर्णन किया गया है blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/…
Ray

20

सामान्य भलाई के अवरोही क्रम में, यहाँ कई समाधान हैं:

1. default(CancellationToken)डिफ़ॉल्ट मान के रूप में उपयोग करना :

Task DoAsync(CancellationToken ct = default(CancellationToken)) {  }

शब्दार्थ, CancellationToken.Noneडिफ़ॉल्ट के लिए आदर्श उम्मीदवार होगा, लेकिन इसका उपयोग इस तरह नहीं किया जा सकता क्योंकि यह संकलन-समय स्थिर नहीं है। default(CancellationToken)यह अगली सबसे अच्छी बात है क्योंकि यह एक संकलन-समय स्थिर है और आधिकारिक तौर पर इसके समकक्ष होने के लिए प्रलेखित हैCancellationToken.None

2. बिना एक विधि अधिभार प्रदान करना a CancellationToken पैरामीटर के :

या, यदि आप वैकल्पिक मापदंडों पर विधि अधिभार पसंद करते हैं ( यह और उस विषय पर यह प्रश्न देखें ):

Task DoAsync(CancellationToken ct) {  } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token

इंटरफ़ेस विधियों के लिए, एक्सटेंशन विधियों का उपयोग करके समान प्राप्त किया जा सकता है:

interface IFoo
{
    Task DoAsync(CancellationToken ct);
}

static class Foo
{
    public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}

यह एक स्लिमर इंटरफ़ेस में परिणाम करता है और कार्यान्वयनकर्ताओं को अग्रेषण विधि अधिभार को स्पष्ट रूप से लिखने से रोकता है।

3. पैरामीटर को अशक्त बनाना और nullडिफ़ॉल्ट मान के रूप में उपयोग करना :

Task DoAsync(…, CancellationToken? ct = null)
{
     ct ?? CancellationToken.None 
}

मुझे यह समाधान कम से कम पसंद है क्योंकि अशक्त प्रकार एक छोटे रनटाइम ओवरहेड के साथ आते हैं, और निरस्त टोकन के संदर्भ में अशक्त सहकर्मी ऑपरेटर के कारण अधिक क्रिया हो जाते हैं ??


11

एक अन्य विकल्प एक Nullable<CancellationToken>पैरामीटर का उपयोग करना है, इसे डिफ़ॉल्ट रूप से nullऔर विधि के अंदर से निपटना है:

Task<x> DoStuff(...., CancellationToken? ct = null) {
    var token = ct ?? CancellationToken.None;
    ...
}

प्रतिभाशाली! अब तक यह सबसे अच्छा जवाब है
जॉन हेंकेल

4

C # के नए संस्करण डिफ़ॉल्ट (कैंसिलेशनटोकन) संस्करण के लिए एक सरलीकृत वाक्यविन्यास के लिए अनुमति देते हैं। उदाहरण के लिए:

Task<x> DoStuff(...., CancellationToken ct = default)

-1

टोफुटिम का जवाब एक तरह से है, लेकिन टिप्पणियों से मुझे लगता है कि लोगों के पास इसके मुद्दे हैं।

उस मामले में, मैंने सुझाव दिया कि एक विधि निम्नानुसार हो सकती है:

Task<x> DoStuff(...., CancellationToken ct)
{
} 

और इसे इस तरह से ओवरलोड करें:

Task<x> DoStuff(....)
{
    return DoStuff(...., CancellationToken.None);
}

यह संकलित करता है, क्योंकि CancellationToken.Noneसंकलन के समय मूल्य की आवश्यकता नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.