यदि आप अपने तरीके के अंदर async / प्रतीक्षा का उपयोग नहीं करना चाहते हैं, लेकिन फिर भी इसे "सजाएँ" तो बाहर से प्रतीक्षित खोजशब्द का उपयोग करने में सक्षम होने के लिए, TaskCompletionSource.cs :
public static Task<T> RunAsync<T>(Func<T> function)
{
if (function == null) throw new ArgumentNullException(“function”);
var tcs = new TaskCompletionSource<T>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
T result = function();
tcs.SetResult(result);
}
catch(Exception exc) { tcs.SetException(exc); }
});
return tcs.Task;
}
यहाँ से और यहाँ
टास्क के साथ इस तरह के प्रतिमान का समर्थन करने के लिए, हमें टास्क फ़ेकडे और टास्क के रूप में एक मनमाने अतुल्यकालिक ऑपरेशन को संदर्भित करने की क्षमता को बनाए रखने की जरूरत है, लेकिन अंतर्निहित टास्क के नियमों के अनुसार उस टास्क के जीवनकाल को नियंत्रित करने के लिए। अतुल्यकालिक, और ऐसा करने के लिए काफी लागत नहीं है। यह टास्क कॉमप्लेक्शन सोर्स का उद्देश्य है।
मैंने देखा कि इसका उपयोग .NET स्रोत में भी किया जाता है। WebClient.cs :
[HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task<string> UploadStringTaskAsync(Uri address, string method, string data)
{
// Create the task to be returned
var tcs = new TaskCompletionSource<string>(address);
// Setup the callback event handler
UploadStringCompletedEventHandler handler = null;
handler = (sender, e) => HandleCompletion(tcs, e, (args) => args.Result, handler, (webClient, completion) => webClient.UploadStringCompleted -= completion);
this.UploadStringCompleted += handler;
// Start the async operation.
try { this.UploadStringAsync(address, method, data, tcs); }
catch
{
this.UploadStringCompleted -= handler;
throw;
}
// Return the task that represents the async operation
return tcs.Task;
}
अंत में, मुझे निम्नलिखित भी उपयोगी लगे:
मुझे यह सवाल हर समय आता है। निहितार्थ यह है कि बाहरी संसाधन पर I / O कॉल को अवरुद्ध करने वाले कहीं न कहीं कुछ धागा होना चाहिए। तो, एसिंक्रोनस कोड अनुरोध थ्रेड को मुक्त करता है, लेकिन सिस्टम में कहीं और दूसरे थ्रेड की कीमत पर ही सही? नहीं, कदापि नहीं। अतुल्यकालिक अनुरोधों के पैमाने को समझने के लिए, मैं एक अतुल्यकालिक I / O कॉल का (सरलीकृत) उदाहरण ट्रेस करूँगा। मान लें कि किसी फ़ाइल में लिखने के लिए अनुरोध की आवश्यकता है। अनुरोध थ्रेड अतुल्यकालिक लेखन विधि को कॉल करता है। बेस क्लास लाइब्रेरी (BCL) द्वारा WriteAsync लागू किया गया है, और इसके अतुल्यकालिक I / O के लिए पूरा करने वाले बंदरगाहों का उपयोग करता है। इसलिए, WriteAsync कॉल OS के लिए एक एसिंक्रोनस फ़ाइल लिखने के रूप में पास की जाती है। OS तब ड्राइवर स्टैक के साथ संचार करता है, जो डेटा के साथ I / O अनुरोध पैकेट (IRP) में लिखता है। यही हैं जहां बातें दिलचस्प हो जाती हैं: यदि कोई डिवाइस ड्राइवर IRP को तुरंत हैंडल नहीं कर सकता है, तो उसे इसे एसिंक्रोनस रूप से हैंडल करना होगा। तो, ड्राइवर डिस्क को लिखना शुरू करने के लिए कहता है और ओएस के लिए "लंबित" प्रतिक्रिया देता है। ओएस बीसीएल के लिए "लंबित" प्रतिक्रिया पारित करता है, और बीसीएल अनुरोध-हैंडलिंग कोड के लिए एक अधूरा काम देता है। अनुरोध-हैंडलिंग कोड उस कार्य की प्रतीक्षा करता है, जो उस विधि और इतने पर से अपूर्ण कार्य देता है। अंत में, अनुरोध-हैंडलिंग कोड ASP.NET के लिए एक अधूरा कार्य वापस लौटता है, और अनुरोध थ्रेड थ्रेड पूल पर लौटने के लिए मुक्त हो जाता है। अनुरोध-हैंडलिंग कोड उस कार्य की प्रतीक्षा करता है, जो उस विधि और इतने पर से अपूर्ण कार्य देता है। अंत में, अनुरोध-हैंडलिंग कोड ASP.NET के लिए एक अधूरा कार्य वापस लौटता है, और अनुरोध थ्रेड थ्रेड पूल पर लौटने के लिए मुक्त हो जाता है। अनुरोध-हैंडलिंग कोड उस कार्य की प्रतीक्षा करता है, जो उस विधि और इतने पर से अपूर्ण कार्य देता है। अंत में, अनुरोध-हैंडलिंग कोड ASP.NET के लिए एक अधूरा कार्य वापस लौटता है, और अनुरोध थ्रेड थ्रेड पूल पर लौटने के लिए मुक्त हो जाता है।
ASP.NET पर Async / Await का परिचय
यदि लक्ष्य मापनीयता (जवाबदेही के बजाय) में सुधार करना है, तो यह सब बाहरी I / O के अस्तित्व पर निर्भर करता है जो ऐसा करने का अवसर प्रदान करता है।