private void RunAsync()
{
string param = "Hi";
Task.Run(() => MethodWithParameter(param));
}
private void MethodWithParameter(string param)
{
}
संपादित करें
लोकप्रिय मांग के कारण मुझे ध्यान देना चाहिए कि Task
लॉन्चिंग कॉलिंग थ्रेड के साथ समानांतर में चलेगा। डिफ़ॉल्ट मानकर TaskScheduler
यह .NET का उपयोग करेगा ThreadPool
। वैसे भी, इसका मतलब है कि आपको जो भी पैरामीटर (ओं) को पारित करने की आवश्यकता हैTask
ही समय में कई थ्रेड्स द्वारा एक्सेस किए जा रहे जितने , उन्हें साझा स्थिति बनाते हैं। इसमें उन्हें कॉलिंग थ्रेड पर एक्सेस करना शामिल है।
मेरे उपरोक्त कोड में उस मामले को पूरी तरह से बनाया गया है। तार अपरिवर्तनीय हैं। इसलिए मैंने उन्हें एक उदाहरण के रूप में इस्तेमाल किया। लेकिन कहते हैं कि तुम एक का उपयोग नहीं कर रहे हैंString
...
एक समाधान का उपयोग करना है async
और await
। यह, डिफ़ॉल्ट रूप से, SynchronizationContext
कॉलिंग थ्रेड को कैप्चर करेगा और कॉल करने के बाद शेष विधि के लिए एक निरंतरता बनाएगा await
और इसे बनाए गए से संलग्न करेगा Task
। यदि यह विधि WinForms GUI थ्रेड पर चल रही है, तो यह प्रकार की होगीWindowsFormsSynchronizationContext
।
निरंतर कब्जा किए जाने के बाद वापस चलेगा SynchronizationContext
- केवल डिफ़ॉल्ट रूप से। तो आप उस थ्रेड पर वापस आ जाएंगे जिसे आपने await
कॉल के बाद शुरू किया था । आप इसे विभिन्न तरीकों से बदल सकते हैं, विशेष रूप से उपयोग करके ConfigureAwait
। संक्षेप में, उस विधि के बाकी तक जारी नहीं किया जाएगा के बादTask
किसी अन्य धागे पर पूरा । लेकिन कॉलिंग थ्रेड समानांतर में चलता रहेगा, बाकी का तरीका नहीं।
शेष विधि को पूरा करने के लिए यह प्रतीक्षा वांछनीय हो सकती है या नहीं भी हो सकती है। यदि उस पद्धति में कुछ भी नहीं है, तो बाद में Task
आपके पास दिए गए मापदंडों को एक्सेस करता है जो आप उपयोग नहीं करना चाहते हैं await
।
या हो सकता है कि आप उन मापदंडों का उपयोग विधि में बहुत बाद में करें। await
तुरंत कोई कारण नहीं क्योंकि आप सुरक्षित रूप से काम करना जारी रख सकें। याद रखें, आप Task
एक चर में और await
बाद में लौटा स्टोर कर सकते हैं - यहां तक कि एक ही विधि में भी। उदाहरण के लिए, एक बार जब आप किसी अन्य कार्य को करने के बाद सुरक्षित रूप से पारित मापदंडों का उपयोग करने की आवश्यकता होती है। फिर, आप पर करने की जरूरत नहींawait
हैTask
इसे चलाने दाईं ओर की है।
वैसे भी, यह करने के लिए पारित मापदंडों के संबंध में इस धागे को सुरक्षित बनाने का एक सरल तरीका है Task.Run
:
आप पहली बार सजाने चाहिए RunAsync
साथ async
:
private async void RunAsync()
महत्वपूर्ण लेख
अधिमानतः चिह्नित विधि को शून्य नहीं लौटना चाहिए , क्योंकि लिंक किए गए दस्तावेज़ में उल्लेख है। इसका सामान्य अपवाद ईवेंट हैंडलर जैसे बटन क्लिक और ऐसे हैं। उन्हें शून्य लौटना चाहिए। अन्यथा मैं हमेशा एक वापसी का उपयोग करते समय या कोशिश करता हूं । यह काफी कुछ कारणों से अच्छा अभ्यास है।async
Task
Task<TResult>
async
अब आप नीचे await
की Task
तरह चला सकते हैं। आप await
बिना उपयोग नहीं कर सकते async
।
await Task.Run(() => MethodWithParameter(param));
तो, सामान्य तौर पर, यदि आप await
कार्य करते हैं , तो आप एक ही बार में कई थ्रेड से कुछ संशोधित करने के सभी नुकसान के साथ संभावित साझा संसाधन के रूप में मापदंडों में पारित उपचार से बच सकते हैं। इसके अलावा, बंद होने से सावधान रहें । मैं उन लोगों को गहराई से कवर नहीं करूंगा, लेकिन जुड़ा हुआ लेख इसका एक बड़ा काम करता है।
पक्षीय लेख
थोड़ा सा विषय, लेकिन WinForms GUI थ्रेड पर किसी भी प्रकार के "ब्लॉकिंग" का उपयोग करने से सावधान रहें क्योंकि इसे चिह्नित किया जा रहा है [STAThread]
। उपयोग await
करना बिल्कुल भी ब्लॉक नहीं होगा, लेकिन मैं कभी-कभी इसे किसी प्रकार के अवरोधन के साथ संयोजन के रूप में उपयोग करते हुए देखता हूं।
"ब्लॉक" उद्धरण में है क्योंकि आप तकनीकी रूप से WinForms GUI थ्रेड को ब्लॉक नहीं कर सकते हैं । हां, अगर आप lock
WinForms GUI थ्रेड का उपयोग करते हैं, तो यह अभी भी संदेशों को पंप करेगा , आपके सोचने के बावजूद कि यह "अवरुद्ध" है। यह।
यह बहुत दुर्लभ मामलों में विचित्र मुद्दों का कारण बन सकता है। lock
उदाहरण के लिए, एक कारण जब आप कभी भी पेंटिंग का उपयोग नहीं करना चाहते हैं । लेकिन यह एक फ्रिंज और जटिल मामला है; हालाँकि मैंने देखा है कि यह पागल मुद्दों का कारण है। इसलिए मैंने इसे संपूर्णता के लिए नोट किया।