सबसे पहले, चलो कुछ शब्दावली को स्पष्ट करते हैं: "अतुल्यकालिक" ( async
) का अर्थ है कि यह शुरू होने से पहले कॉलिंग थ्रेड पर वापस नियंत्रण प्राप्त कर सकता है। एक async
विधि में, उन "उपज" अंक await
अभिव्यक्ति हैं।
यह "एसिंक्रोनस" शब्द से बहुत अलग है, जैसा कि (मिस) MSDN प्रलेखन द्वारा वर्षों से उपयोग किया जाता है, जिसका अर्थ है "एक पृष्ठभूमि धागे पर निष्पादित"।
फ़्यूचर को इस मुद्दे को भ्रमित करने के लिए, async
"प्रतीक्षा योग्य" से बहुत अलग है; कुछ async
विधियाँ हैं जिनकी वापसी प्रकार प्रतीक्षा योग्य नहीं हैं, और कई विधियाँ प्रतीक्षा योग्य प्रकार हैं जो नहीं हैं async
।
वे क्या नहीं कर रहे हैं के बारे में पर्याप्त ; यहाँ वे क्या हैं :
async
कीवर्ड एक अतुल्यकालिक विधि की अनुमति देता है (यह है कि, यह अनुमति देता है await
भाव)। async
विधियां वापस आ सकती हैं Task
, Task<T>
या (यदि आपको चाहिए) void
।
- किसी भी प्रकार जो एक निश्चित पैटर्न का अनुसरण करता है, वह प्रतीक्षा योग्य हो सकता है। सबसे आम प्रतीक्षित प्रकार हैं
Task
और Task<T>
।
इसलिए, यदि हम आपके प्रश्न को "मैं एक पृष्ठभूमि थ्रेड पर ऑपरेशन कैसे चला सकता हूं , जो इस तरह से प्रतीक्षा योग्य है", तो इसका उपयोग करना है Task.Run
:
private Task<int> DoWorkAsync() // No async because the method does not need await
{
return Task.Run(() =>
{
return 1 + 2;
});
}
(लेकिन यह पैटर्न एक खराब दृष्टिकोण है; नीचे देखें)।
लेकिन अगर आपका सवाल है "मैं एक async
विधि कैसे बनाऊं जो अवरोधक के बजाय इसके कॉलर को वापस प्राप्त कर सकती है", तो इसका उत्तर विधि async
और await
उसके "उपज" बिंदुओं के लिए उपयोग करना है:
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.example.com/");
return html.Length;
}
तो, चीजों का मूल पैटर्न async
कोड का उसके await
भावों में "प्रतीक्षा-योग्यताओं" पर निर्भर होना है । ये "वेटिटेबल्स" अन्य async
विधियां हो सकती हैं या नियमित रूप से वेटीबल्स लौटा सकती हैं। लौटने नियमित तरीकों Task
/ Task<T>
कर सकते हैं का उपयोग Task.Run
एक पृष्ठभूमि धागे पर कोड निष्पादित करने के लिए, या (सामान्यतः) वे उपयोग कर सकते हैं TaskCompletionSource<T>
या अपने शॉर्टकट (में से एक TaskFactory.FromAsync
, Task.FromResult
, आदि)। मैं एक पूरी विधि को लपेटने की सलाह नहीं देता Task.Run
; सिंक्रोनस मेथड्स में सिंक्रोनस सिग्नेचर होना चाहिए, और इसे उपभोक्ता तक छोड़ दिया जाना चाहिए, चाहे वह इसमें लिपटे हों Task.Run
:
private int DoWork()
{
return 1 + 2;
}
private void MoreSynchronousProcessing()
{
// Execute it directly (synchronously), since we are also a synchronous method.
var result = DoWork();
...
}
private async Task DoVariousThingsFromTheUIThreadAsync()
{
// I have a bunch of async work to do, and I am executed on the UI thread.
var result = await Task.Run(() => DoWork());
...
}
मैं एक है async
/ await
परिचय अपने ब्लॉग पर; अंत में कुछ अच्छे फॉलोअप संसाधन हैं। MSDN डॉक्स async
असामान्य रूप से अच्छे हैं, भी।