C # आपको ओवरराइड एसिंक्स बनाने की अनुमति क्यों देता है?


16

C # में, जब आप किसी विधि को ओवरराइड करते हैं, तो मूल विधि नहीं होने पर ओवरराइड को एसिंक्रोन बनाने की अनुमति होती है। यह खराब फॉर्म की तरह लगता है।

उदाहरण जो मुझे इस पर लाया गया था, वह था - मुझे लोड टेस्ट की समस्या से सहायता के लिए लाया गया था। लगभग 500 समवर्ती उपयोगकर्ताओं पर, लॉगिन प्रक्रिया एक अनुप्रेषित लूप में टूट जाएगी। IIS संदेश के साथ अपवादों को लॉग कर रहा था "एक अतुल्यकालिक मॉड्यूल या हैंडलर पूरा हुआ जबकि एक अतुल्यकालिक ऑपरेशन अभी भी लंबित था"। कुछ खोज ने मुझे यह सोचने के लिए प्रेरित किया कि कोई व्यक्ति दुर्व्यवहार कर रहा था async void, लेकिन स्रोत के माध्यम से मेरी त्वरित खोजें कुछ भी नहीं पा सकीं।

अफसोस की बात है कि मैं 'async \ svoid' (regex खोज) की खोज कर रहा था, जब मुझे 'async \ s [^ T] जैसी कुछ और चीज़ों की तलाश में होना चाहिए था (यह मानकर कार्य पूरी तरह से योग्य नहीं था ... आपको बात मिल जाएगी)।

मुझे बाद में जो मिला वह async override void onActionExecuting(...आधार नियंत्रक में था। स्पष्ट रूप से यह समस्या थी, और यह थी। इसे ठीक करना (पल के लिए इसे समकालिक बनाना) ने समस्या को हल कर दिया।

इस सवाल पर वापस जाएं: क्यों ओह जब आप कॉल कोड का कभी इंतजार नहीं कर सकते, तो आप एक ओवरराइड को async के रूप में चिह्नित क्यों कर सकते हैं?



ओवरराइड विधि का इंतजार करने के लिए क्या वास्तव में एक कॉलर को रोकता है? मुझे कोई बाधा नहीं दिखती।
मार्टिन मेट

@MartinMaat आप केवल वापसी के तरीकों का इंतजार कर सकते हैं Task
डेरेक एल्किंस ने एसई

शायद यह ठीक बात है जिस पर मैंने गौर नहीं किया। मुझे जांच करनी होगी, लेकिन मुझे याद नहीं है कि बिना प्रतीक्षा के गैर-एस्किंक तरीकों को लागू करने के बारे में वी.एस. चेतावनी।
पीटर टी। लाकॉम्ब जूनियर

जवाबों:


16

Async कीवर्ड की अनुमति देता है विधि का उपयोग करने के awaitअपने परिभाषा के दायरे में वाक्य रचना। मैं awaitकिसी भी विधि पर कर सकता हूं जो एक Taskप्रकार का रिटर्न देता है चाहे वह एक एस्किंस विधि हो।

voidएक async विधि के लिए एक कानूनी (यद्यपि हतोत्साहित ) रिटर्न प्रकार है, तो इसकी अनुमति क्यों नहीं दी जाएगी? बाहर से, asyncआप इसके बिना कुछ भी नहीं कर सकते। जिस विधि से आपको परेशानी हो रही है, वह बिना एसिंक्स के समान व्यवहार करने के लिए लिखी जा सकती थी। इसकी परिभाषा बस अधिक क्रिया होगी।

कॉल करने वालों के लिए, एक async Tविधि एक सामान्य विधि है जो वापस आती है T(जो कि , या void, तक सीमित है )। यह एक async विधि इंटरफ़ेस का हिस्सा नहीं है। ध्यान दें कि निम्नलिखित कोड अवैध है:TaskTask<A>

interface IFoo {
    async void Bar();
}

यह (या एक समान श्रेणी में समान कोड) VS2012 में निम्न त्रुटि संदेश उत्पन्न करता है:

'Async' संशोधक का उपयोग केवल उन्हीं विधियों में किया जा सकता है जिनमें कथन बॉडी होती है

यदि मैंने इंटरफ़ेस या पैरेंट क्लास में आमतौर पर अतुल्यकालिक होने के लिए एक विधि का इरादा किया था , तो मैं इसका उपयोग asyncकरने के लिए संचार नहीं कर सकता । अगर मैं इसे awaitसिंटैक्स के साथ लागू करना चाहता था , तो मुझे async ओवरराइड विधियों (मूल वर्ग मामले में) की आवश्यकता होगी।


1
आप बिल्कुल भी उल्लेख नहीं करते override, लेकिन यही सवाल है।
नाथन तुग्गी

5
@NathanTuggy जवाब का पूरा बिंदु यह है कि asyncएक विधि का इंटरफ़ेस नहीं बदलता है, केवल इसकी परिभाषा में वाक्यविन्यास की अनुमति है, इसलिए यह ओवरराइड है या नहीं यह पूरी तरह अप्रासंगिक है।
डेरेक एल्किंस ने 19

1
कृपया समझाएं कि, सभी को संभालने के बजाय पहले से ही सब कुछ प्रासंगिक है।
नाथन तुग्गी

2
@NathanTuggy मुझे लगता है कि मैंने इसे समझाया है। क्या आप एक विशिष्ट प्रश्न पूछ सकते हैं जिसके बारे में आप भ्रमित हैं या आप कल्पना करते हैं कि कोई अन्य भ्रमित व्यक्ति पूछेगा? केवल एक चीज जो मैं जोड़ना चाहता हूं, वह यह है कि asyncसंशोधक को केवल कार्यान्वयन पर लागू किया जा सकता है। आप किसी इंटरफ़ेस में किसी विधि को async घोषित नहीं कर सकते, उदाहरण के लिए, यह रेखांकित करना कि कोई विधि async है या नहीं, इंटरफ़ेस का हिस्सा नहीं है।
डेरेक एलकिंस ने 20

5
स्पष्टीकरण को उत्तर में रखो , मेरा मतलब है। यह लंबे समय के लिए टिप्पणी नहीं है।
नाथन तुग्गी

10

Async कीवर्ड का एकमात्र उद्देश्य उस फ़ंक्शन के मुख्य भाग के भीतर प्रतीक्षा करना है। इसकी आवश्यकता है ताकि प्रतीक्षित कार्यक्षमता जोड़ने से मौजूदा कोड न टूटे। Microsoft ने ऑप्ट-इन विकल्प का उपयोग करने का निर्णय लिया। एक फ़ंक्शन के लिए जो async के रूप में चिह्नित नहीं है, आप किसी समस्या के साथ प्रतीक्षा नाम के एक चर को परिभाषित कर सकते हैं।

इसलिए async किसी फ़ंक्शन के हस्ताक्षर का हिस्सा नहीं है और उत्पन्न IL कोड में इसका कोई अर्थ नहीं है। यह कंपाइलर के लिए कड़ाई से पता है कि फ़ंक्शन को सही तरीके से कैसे संकलित किया जाए। यह संकलक को यह सुनिश्चित करने के लिए भी निर्देश देता है कि केवल टास्क, टास्क <टी> या शून्य वापस किया जा रहा है।

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