बस VS2012 मिल गया और एक संभाल पाने की कोशिश कर रहा है async
।
मान लीजिए कि मुझे एक विधि मिली है जो एक अवरुद्ध स्रोत से कुछ मूल्य प्राप्त करती है। मुझे ब्लॉक करने की विधि का कॉलर नहीं चाहिए। मैं कॉलबैक लेने के लिए विधि लिख सकता हूं, जो मान आने पर आह्वान किया जाता है, लेकिन जब से मैं C # 5 का उपयोग कर रहा हूं, मैं इस पद्धति को बनाने का निर्णय लेता हूं ताकि कॉल करने वालों को कॉलबैक से निपटने की आवश्यकता न हो:
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
यहां एक उदाहरण विधि है जो इसे कॉल करती है। यदि PromptForStringAsync
यह नहीं था, तो इस पद्धति में कॉलबैक के लिए कॉलबैक की आवश्यकता होगी। Async के साथ, मुझे अपनी विधि को बहुत ही स्वाभाविक तरीके से लिखना है:
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
अब तक सब ठीक है। समस्या यह है कि जब मैं GetNameAsync को कॉल करता हूं:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
पूरे बिंदु GetNameAsync
यह है कि यह अतुल्यकालिक है। मुझे नहीं चाहिए इसे ब्लॉक , क्योंकि मैं MainWorkOfApplicationIDontWantBlocked ASAP पर वापस जाना चाहता हूं और GetNameAsync को पृष्ठभूमि में अपनी बात करने देता हूं। हालाँकि, इसे इस तरह से बुलाना मुझे GetNameAsync
लाइन पर एक संकलक चेतावनी देता है :
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
मुझे पूरी तरह से पता है कि "कॉल पूरा होने से पहले मौजूदा पद्धति का निष्पादन जारी है"। वह है अतुल्यकालिक कोड बात है, है ना?
मैं अपने कोड को चेतावनी के बिना संकलित करना पसंद करता हूं, लेकिन यहां "ठीक" करने के लिए कुछ भी नहीं है क्योंकि कोड बिल्कुल वही कर रहा है जो मैं इसे करने का इरादा रखता हूं। की रिटर्न वैल्यू को स्टोर करके मैं चेतावनी से छुटकारा पा सकता हूंGetNameAsync
:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
लेकिन अब मेरे पास सुपरफ्लस कोड है। विज़ुअल स्टूडियो को यह समझ में आता है कि मुझे यह अनावश्यक कोड लिखने के लिए मजबूर किया गया था, क्योंकि यह सामान्य "मूल्य कभी इस्तेमाल नहीं" चेतावनी को दबा देता है।
मैं GetNameAsync को एक ऐसी विधि में लपेट कर चेतावनी से छुटकारा पा सकता हूँ जो कि async नहीं है:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
लेकिन यह और भी अधिक है ज़रूरत से ज़्यादा कोड। इसलिए मुझे एक अनावश्यक चेतावनी देने के लिए कोड लिखने की ज़रूरत नहीं है।
क्या मेरे यहाँ async के उपयोग के बारे में कुछ गलत है?
GetNameAsync
पूरा नाम है कि उपयोगकर्ता द्वारा प्रदान किया गया (यानी प्रदान करने के लिए Task<Name>
है, न कि सिर्फ एक लौटने से Task
? DoStuff
और या तो उसके बाद उस कार्य को संग्रहीत कर सकती है, await
यह बाद अन्य विधि, या यहाँ तक कि कार्य है कि अन्य को पारित विधि तो यह कर सकता है await
या Wait
इसे कहीं यह के कार्यान्वयन के अंदर।
async
कीवर्ड निकालें ।
PromptForStringAsync
आप लागू करते हैं तो आपको जरूरत से ज्यादा काम करना पड़ता है; के परिणाम को वापस करेंTask.Factory.StartNew
। यह पहले से ही एक कार्य है जिसका मूल्य कंसोल में दर्ज स्ट्रिंग है। परिणाम लौटाने के लिए इसका इंतजार करने की कोई आवश्यकता नहीं है; ऐसा करने से कोई नया मूल्य नहीं जुड़ता है।