सवाल सी # Async - यह कैसे काम करता है?


माइक्रोसॉफ्ट ने घोषणा की विजुअल स्टूडियो Async सीटीपी आज (28 अक्टूबर, 2010) जो परिचय देता है async तथा await एसिंक्रोनस विधि निष्पादन के लिए सी # / वीबी में कीवर्ड।

सबसे पहले मैंने सोचा कि संकलक कीवर्ड को धागे के निर्माण में अनुवाद करता है लेकिन इसके अनुसार सफ़ेद कागज और एंडर्स हेजल्सबर्ग पीडीसी प्रस्तुति (31:00 बजे) एसिंक्रोनस ऑपरेशन मुख्य धागे पर पूरी तरह से होता है।

मैं एक ही धागे पर समानांतर में निष्पादित एक ऑपरेशन कैसे कर सकता हूं? यह तकनीकी रूप से संभव कैसे है और वास्तव में आईएल में किस सुविधा का अनुवाद किया गया है?


44
2017-10-28 21:47


मूल




जवाब:


यह इसी तरह काम करता है yield return सी # 2.0 में कीवर्ड।

एक असीमित विधि वास्तव में एक सामान्य अनुक्रमिक विधि नहीं है। यह कुछ राज्य के साथ एक राज्य मशीन (एक वस्तु) में संकलित है (स्थानीय चर वस्तु के क्षेत्रों में बदल जाते हैं)। कोड के प्रत्येक ब्लॉक के दो प्रयोगों के बीच await राज्य मशीन का एक "कदम" है।

इसका अर्थ यह है कि जब विधि शुरू होती है, तो यह केवल पहला कदम चलाती है और फिर राज्य मशीन लौटाती है और कुछ काम करने के लिए शेड्यूल करता है - जब काम पूरा हो जाता है, तो यह राज्य मशीन का अगला चरण चलाएगा। उदाहरण के लिए यह कोड:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

कुछ इस तरह अनुवाद किया जाएगा:

class _Demo {
  int _v1, _v2;
  int _state = 0; 
  Task<int> _await1;
  public void Step() {
    switch(this._state) {
    case 0: 
      this._v1 = foo();
      this._await1 = bar();
      // When the async operation completes, it will call this method
      this._state = 1;
      op.SetContinuation(Step);
    case 1:
      this._v2 = this._await1.Result; // Get the result of the operation
      more(this._v1, this._v2);
  }
}

महत्वपूर्ण हिस्सा यह है कि यह सिर्फ उपयोग करता है SetContinuation यह निर्दिष्ट करने के लिए कि जब ऑपरेशन पूरा हो जाता है, तो उसे कॉल करना चाहिए Step विधि फिर से (और विधि जानता है कि इसे मूल कोड का दूसरा बिट चलाकर चलाना चाहिए _state खेत)। आप आसानी से कल्पना कर सकते हैं कि SetContinuation कुछ ऐसा होगा btn.Click += Step, जो पूरी तरह से एक धागे पर चला जाएगा।

सी # में एसिंक्रोनस प्रोग्रामिंग मॉडल एफ # असीमित वर्कफ़्लोज़ के बहुत करीब है (वास्तव में, यह अनिवार्य रूप से वही बात है, कुछ तकनीकी विवरणों के अलावा), और प्रतिक्रियाशील एकल-थ्रेडेड जीयूआई अनुप्रयोगों का उपयोग कर async काफी दिलचस्प क्षेत्र है - कम से कम मुझे ऐसा लगता है - उदाहरण के लिए देखें यह लेख (शायद मुझे अब सी # संस्करण लिखना चाहिए :-))।

अनुवाद iterators के समान है (और yield return) और वास्तव में, सी # में पहले एसिंक्रोनस प्रोग्रामिंग को लागू करने के लिए इटरेटर का उपयोग करना संभव था। मैंने लिखा इसके बारे में एक लेख थोड़ी देर पहले - और मुझे लगता है कि यह आपको अभी भी कुछ अंतर्दृष्टि दे सकता है कि अनुवाद कैसे काम करता है।


75
2017-10-28 22:19





मैं एक ही धागे पर समानांतर में निष्पादित एक ऑपरेशन कैसे कर सकता हूं?

आप नहीं कर सकते Asynchrony "समांतरता" या "concurrency" नहीं है। असीमितता समानांतरता के साथ लागू की जा सकती है, या यह नहीं हो सकता है। यह काम को छोटे टुकड़ों में तोड़कर, कतार पर काम के प्रत्येक हिस्से को डालने और फिर जब भी धागा कुछ और नहीं कर रहा होता है तो काम के प्रत्येक हिस्से को निष्पादित करके कार्यान्वित किया जा सकता है।

मेरे ब्लॉग पर लेखों की एक पूरी श्रृंखला है कि यह सब कुछ कैसे काम करता है; इस प्रश्न के लिए सीधे एक जर्मन अगले हफ्ते गुरुवार को जाएगा। घड़ी

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

ब्योरा हेतु।


44
2017-10-29 23:49





जैसा कि मैं समझता हूं, क्या async तथा await कीवर्ड ऐसा करते हैं कि हर बार एक async विधि नियोजित करता है await कीवर्ड, कंपाइलर विधि के शेष को एक निरंतरता में बदल देगा जो निर्धारित है कि एसिंक ऑपरेशन पूरा होने पर निर्धारित किया गया है। वह आज्ञा देता है async कॉलर पर तुरंत लौटने के तरीके और एसिंक भाग होने पर काम फिर से शुरू करें।

उपलब्ध कागजात के मुताबिक इसमें बहुत सारे विवरण हैं, लेकिन जब तक कि मैं गलत नहीं हूं, वह इसका सारांश है।

जैसा कि मैंने देखा है कि एसिंक विधियों का उद्देश्य समानांतर में बहुत से कोड को चलाने के लिए नहीं है, लेकिन एसिंक विधियों को कई छोटे हिस्सों में काटना है, जिन्हें आवश्यकतानुसार कहा जा सकता है। मुख्य बिंदु यह है कि संकलक कार्यों / निरंतरताओं का उपयोग करके कॉलबैक की सभी जटिल तारों को संभालेगा। यह न केवल जटिलता को कम करता है, बल्कि एसिंक विधि को पारंपरिक सिंक्रोनस कोड की तरह कम या कम लिखा जा सकता है।


7
2017-10-28 21:53



यह अलग धागे के बिना कैसे निर्धारित किया जाता है? क्या सीएलआर में एक निरंतर अवधारणा है जो कुछ हल्के वजन शेड्यूलिंग की अनुमति देती है? - Dirk Vollmar
@ 0xA3: मेरा मानना ​​है कि पेपर कहता है कि async विधि अपने स्वयं के धागे पर नहीं चलती है। अर्थात। बस टीपीएल की तरह यह स्थिति के आधार पर वर्तमान धागे और धागे पूल धागे का मिश्रण होगा। - Brian Rasmussen