मेरा तरीका लौट आया Task
। मैं समाप्त होने तक इंतजार करना चाहता हूं। मुझे क्या उपयोग करना चाहिए
.Wait()
या .GetAwaiter().GetResult()
? उनके बीच क्या अंतर है?
मेरा तरीका लौट आया Task
। मैं समाप्त होने तक इंतजार करना चाहता हूं। मुझे क्या उपयोग करना चाहिए
.Wait()
या .GetAwaiter().GetResult()
? उनके बीच क्या अंतर है?
जवाबों:
दोनों ऑपरेशन के परिणाम के लिए एक तुल्यकालिक प्रतीक्षा कर रहे हैं (और यदि संभव हो तो आपको उन लोगों से बचना चाहिए)।
अंतर मुख्य रूप से अपवादों को संभालने में है। इसके साथ Wait
, अपवाद स्टैक ट्रेस अनलॉक्ड है और अपवाद के समय वास्तविक स्टैक का प्रतिनिधित्व करता है, इसलिए यदि आपके पास कोड का एक टुकड़ा है जो थ्रेड-पूल थ्रेड पर चलता है, तो आपके पास एक स्टैक होगा
ThreadPoolThread.RunTask
YourCode.SomeWork
दूसरी ओर, .GetAwaiter().GetResult()
स्टैक ट्रेस को सभी अतुल्यकालिक संदर्भ को ध्यान में रखना होगा, इस बात की अनदेखी करते हुए कि कोड के कुछ भाग UI थ्रेड पर निष्पादित होते हैं, और कुछ थ्रेडपूल थ्रेड पर, और कुछ बस एसिंक्रोनस I / O हैं। इसलिए आपका स्टैक ट्रेस आपके कोड के माध्यम से एक तुल्यकालिक कदम को प्रतिबिंबित करेगा :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
यह कम से कम कहने के लिए अपवाद स्टैक के निशान को अधिक उपयोगी बनाता है। आप देख सकते हैं कि आपके आवेदन के संदर्भ में "भौतिक तरीके से चलाया गया था" के बजाय कहां YourCode.SomeWork
बुलाया गया था।
यह कैसे काम करता है इसका एक उदाहरण संदर्भ स्रोत (निश्चित रूप से गैर-संविदात्मक) में है।
TaskAwaiter
एक कार्यान्वयन विवरण है। दूसरी ओर, प्रतीक्षा करने योग्य / प्रतीक्षारत तंत्र का दस्तावेजीकरण किया जाता है, और डक-टाइपिंग का उपयोग GetAwaiter
किया await
जाता GetEnumerator
है - जैसा कि है foreach
या Dispose
करना है using
। यह सब सी # विनिर्देश में परिभाषित किया गया है, विशेष रूप से उपयोग किए जा रहे वेटर की परवाह किए बिना - ध्यान दें कि Task.GetAwaiter
"अनुप्रयोग कोड में उपयोग के बजाय संकलक उपयोग के लिए अभिप्रेत है।" लेकिन मुद्दा यह है कि इच्छित उपयोग ए await
, न करने के लिए है - न Wait()
ही GetAwaiter().GetResult()
- लेकिन GetResult
आपको ज़रूरत पड़ने पर आपको अच्छे स्टैक देता है।