2010-10-28 23 views
43

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

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

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

उत्तर

73

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

एक असीमित विधि वास्तव में एक सामान्य अनुक्रमिक विधि नहीं है। यह कुछ राज्य के साथ एक राज्य मशीन (एक वस्तु) में संकलित है (स्थानीय चर वस्तु के क्षेत्रों में बदल जाते हैं)। 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); 
    } 
} 

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

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

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

6

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

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

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

+2

यह एक अलग थ्रेड के बिना कैसे निर्धारित किया जाता है? क्या सीएलआर में एक निरंतर अवधारणा है जो कुछ हल्के वजन शेड्यूलिंग की अनुमति देती है? –

+0

@ 0xA3: मेरा मानना ​​है कि पेपर कहता है कि async विधि अपने स्वयं के धागे पर नहीं चलती है। अर्थात। बस टीपीएल की तरह यह स्थिति के आधार पर वर्तमान धागे और धागे पूल धागे का मिश्रण होगा। –

43

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

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

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

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

जानकारी के लिए

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