क्या मुझे 'async शून्य' घटना संचालकों से बचना चाहिए?


119

मुझे पता है कि आम तौर पर async voidकार्यों को शुरू करने के लिए आग और भूल जाने वाली विधियों का उपयोग करना एक बुरा विचार माना जाता है, क्योंकि लंबित कार्य का कोई ट्रैक नहीं है और यह अपवादों को संभालने के लिए मुश्किल है जो इस तरह की विधि के अंदर फेंक दिया जा सकता है।

क्या मुझे आम तौर पर async voidइवेंट हैंडलर से बचना चाहिए ? उदाहरण के लिए,

private async void Form_Load(object sender, System.EventArgs e)
{
        await Task.Delay(2000); // do async work
        // ...
} 

मैं इसे इस तरह से फिर से लिख सकता हूं:

Task onFormLoadTask = null; // track the task, can implement cancellation

private void Form_Load(object sender, System.EventArgs e)
{
        this.onFormLoadTask = OnFormLoadTaskAsync(sender, e);
} 

private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e)
{
        await Task.Delay(2000); // do async work
        // ...
} 

एसिंक्स इवेंट हैंडलर के लिए पानी के नीचे की चट्टानें, संभावित फिर से प्रवेश के अलावा क्या हैं?


आपको चाहिए लेकिन आप नहीं कर सकते। इसके अलावा, यूआईएन इवेंट हैंडलर द्वारा पहले से ही आवश्यक सभी कारों का उपयोग करना चाहिए जो कि एसिंक्स शून्य का उपयोग करना आवश्यक है।
पालो मोरागडो

और पुनरावृत्ति इवेंट हैंडलर द्वारा निकाले गए अतुल्यकालिक ऑपरेशनों के कारण होती है, न कि खुद के लिए एसिंक्स-वेट के उपयोग से।
पाउलो मोरागडो

जवाबों:


153

ईवेंट हैंडलर में उपयोग किए जाने के async void अलावा गाइडलाइन से बचना है , इसलिए ईवेंट हैंडलर का उपयोग async voidकरना ठीक है।

कहा कि, यूनिट परीक्षण कारणों से मैं अक्सर सभी async voidतरीकों के तर्क को जानना चाहता हूं । उदाहरण के लिए,

public async Task OnFormLoadAsync(object sender, EventArgs e)
{
  await Task.Delay(2000);
  ...
}

private async void Form_Load(object sender, EventArgs e)
{
  await OnFormLoadAsync(sender, e);
}

मैं उत्सुक हूँ ... क्या कोई कारण है कि आप सिर्फ अपनी Form_Loadपहुँच नहीं बदलते हैं public? ऐसा लगता है कि कोड इस तरह कम क्रिया होगा।
InteXX

उफ़, कोई बात नहीं ... VBer C # को यहाँ पढ़ने की कोशिश कर रहा है ... मैंने अभी वापसी के प्रकार पर ध्यान दिया है OnFormLoadAsync। अब मैं देखता हूं कि यह एक आसान चाल के लिए बनाता है। धन्यवाद।
InteXX

सभी ने कहा, क्या आप एक नज़र डाल सकते हैं और एक राय पेश कर सकते हैं । धन्यवाद!
InteXX

2
@ AlexHopeO'Connor: Handledध्वज को समान रूप से सेट किया जाना चाहिए; asyncईवेंट को संभाला जाए या नहीं, इस पर निर्णय लेने के लिए उपयोग करना संभव नहीं है।
स्टीफन क्लीयर

2
@ AlexHopeO'Connor: जब से मैंने WPF ऐप के साथ काम किया है, तब से कुछ समय हो गया है, लेकिन मैंने अतीत में इसके समान समाधानों का उपयोग किया है। यानी, ICommand.Executeविधि बनाओ async void; मैं इस पर विचार स्वीकार्य के बाद से ICommand.Executeहै तार्किक एक ईवेंट हैंडलर।
स्टीफन क्लीयर

50

मैं आमतौर पर async शून्य घटना संचालकों से बचना चाहिए, साथ ही?

आम तौर पर ईवेंट हैंडलर एक ऐसा मामला होता है, जहां एक शून्य async विधि एक संभावित कोड गंध नहीं होती है।

अब, यदि आपको किसी कारण से कार्य को ट्रैक करने की आवश्यकता है, तो आपके द्वारा वर्णित तकनीक पूरी तरह से उचित है।


6

हां, आमतौर पर ईवेंट हैंडलर का एसिंक्स शून्य एकमात्र मामला है। यदि आप इसके बारे में अधिक जानना चाहते हैं, तो आप यहां चैनल 9 पर एक शानदार वीडियो देख सकते हैं

The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".

यहाँ लिंक है


' शीर्ष-स्तरीय ईवेंट-हैंडलर ' एक महत्वपूर्ण संकेत है। निचले स्तर के ईवेंट हैंडलर पर async void ईवेंट हैंडलर का उपयोग करते समय यह अपवाद नहीं पकड़े जाने के साथ भारी समस्या पैदा कर सकता है।
पोर्टिकस

वीडियो लिंक के लिए धन्यवाद, बहुत उपयोगी
lsp

5

यदि आप ReSharper का उपयोग करते हैं, तो एक नि: शुल्क ReCommended एक्सटेंशन आपके लिए उपयोगी हो सकता है। यह अनुचित रूप से उपयोग किए जाने पर "एसिंक्स शून्य" विधियों और हाइलाइट्स का विश्लेषण करता है। यह विस्तार अलग-अलग usages के async शून्य को भेद कर सकता है और यहां वर्णित उचित त्वरित सुधार प्रदान कर सकता है: ReCommended-Extension wiki

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.