मैं काफी Task.Wait
और के बीच का अंतर नहीं समझताawait
।
मैं ASP.NET WebAPI सेवा में निम्नलिखित कार्यों के समान है:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Get
गतिरोध कहां होगा?
इसका क्या कारण हो सकता है? जब मैं इसके बजाय अवरुद्ध प्रतीक्षा का उपयोग करता हूं तो यह समस्या क्यों नहीं है await Task.Delay
?
Task.Delay(1).Wait()
मूल रूप से के रूप में सटीक एक ही बात है Thread.Sleep(1000)
। वास्तविक उत्पादन कोड में यह शायद ही उचित है।
WaitAll
गतिरोध पैदा हो रहा है। अधिक विवरण के लिए मेरे उत्तर में मेरे ब्लॉग का लिंक देखें। आपको await Task.WhenAll
इसके बजाय उपयोग करना चाहिए ।
ConfigureAwait(false)
एक एकल कॉल है Bar
या Ros
गतिरोध नहीं है, लेकिन क्योंकि आपके पास एक एन्यूमरेबल है जो एक से अधिक निर्माण कर रहा है और फिर उन सभी पर प्रतीक्षा कर रहा है, पहली बार दूसरी गतिरोध करेगा। यदि आप await Task.WhenAll
सभी कार्यों पर प्रतीक्षा करने के बजाय, ताकि आप एएसपी संदर्भ को अवरुद्ध न करें, तो आप विधि को सामान्य रूप से वापस देखेंगे।
.ConfigureAwait(false)
पेड़ को ब्लॉक करने तक सभी तरह से जोड़ना होगा , इस तरह कुछ भी कभी भी मुख्य संदर्भ में वापस लाने की कोशिश नहीं कर रहा है; इससे काम बन जाएगा। एक अन्य विकल्प एक आंतरिक सिंक्रनाइज़ेशन संदर्भ को स्पिन करना होगा। लिंक करें । आप डाल दिया Task.WhenAll
एक में AsyncPump.Run
यह प्रभावी रूप से आप के लिए जरूरत के बिना पूरी बात पर अवरुद्ध कर देगा ConfigureAwait
कहीं भी, लेकिन शायद एक overly-जटिल समाधान है कि।
Task.Delay(1).Wait()
जिसके साथ काफी अच्छा है।