2010-05-12 11 views
10

एक रूप में,एक संदेश बॉक्स को आमंत्रित करने और शुरू करने के बीच क्या अंतर है?

BeginInvoke (new Action (() => { 
    MessageBox.Show()); 
})); 

तुलना

Invoke (new Action (() => { 
    MessageBox.Show()); 
})); 

क्या फर्क है साथ, और जब मैं एक दूसरे के ऊपर इस्तेमाल करना चाहिए? संदेशबॉक्स के संदेश पंप से प्रभावित व्यवहार कैसा है?

मैंने कुछ परीक्षण किया और पाया कि दोनों विधियां यूआई को अवरुद्ध करती हैं।

केवल अंतर यह है कि Invoke वास्तव में तुरंत कहा जाता है जबकि BeginInvoke कोड चलाए जाने तक एक बहुत ही कम समय लेता है। इसकी उम्मीद की जा रही है।

+0

सभी उत्तरदाताओं के लिए: क्षमा करें, इस समय वोटों से बाहर, कल ऊपर उठने जा रहे हैं :) – mafu

उत्तर

15

BeginInvoke प्रतिनिधि को अतुल्यकालिक रूप से आमंत्रित करेगा, तुरंत वर्तमान धागे के निष्पादन के लिए प्रतिनिधि को कतार में वापस लौटाएगा।

Invoke प्रतिनिधियों को सिंक्रनाइज़ेशन का आह्वान करेगा, जब तक कि प्रतिनिधि पूरा नहीं हो जाता तब तक कॉलिंग थ्रेड को अवरुद्ध कर दिया जाए।

:

BeginInvoke(new Action(()=>Console.WriteLine("BeginInvoke"))); 
Console.WriteLine("AfterBeginInvokeCalled"); 

Invoke(new Action(()=>Console.WriteLine("Invoke"))); 
Console.WriteLine("AfterInvokeCalled"); 

आप निम्नलिखित है, जहां "BeginInvoke" पाठ अपने अतुल्यकालिक निष्पादन की वजह से देरी हो रही है के लिए इसी तरह उत्पादन देखना चाहिए:

अंतर देखने के लिए, निम्नलिखित कोड की कोशिश AfterBeginInvokeCalled
आह्वान
AfterInvokeCalled
BeginInvoke

आपके द्वारा देखे जाने वाले व्यवहार के संबंध में, क्योंकि यह केवल उस प्रतिनिधि को कॉल करने का कार्य है जो तुल्यकालिक या असीमित है; विधि की सामग्री कॉलिंग थ्रेड को रोकने या UI को अवरुद्ध करने का कारण बन सकती है। एक संदेश बॉक्स दिखाने के मामले में, चाहे प्रतिनिधि को BeginInvoke का उपयोग करके देरी हो या नहीं, प्रतिनिधि के नाम पर जाने के बाद, यूआई को तब तक अवरुद्ध कर दिया जाएगा जब तक कि संदेश बॉक्स खारिज नहीं हो जाता।

3

BeginInvoke असीमित है ... इसका मतलब है कि कॉलिंग थ्रेड कॉल करने के लिए बुलाए गए विधि की प्रतीक्षा नहीं करेगा।

तो ठीक है, संवाद बॉक्स हमेशा जीयूआई जमा। लेकिन शुरूआत और आह्वान के बीच का अंतर अब स्पष्ट होना चाहिए:

वापसी करने के लिए बुलाए गए विधि के लिए प्रतीक्षा करें।

+0

मैं सहमत नहीं हूं। संपादित प्रश्न देखें। --- संपादित करें: आह, हाँ, लेकिन संदेशबॉक्स हमेशा मोडल नहीं हैं? – mafu

+0

@ माफुटक्रर्ट: मुझे लगता है कि आपने दो चीजों को भ्रमित कर दिया है। संदेशबॉक्स अभी भी यूआई को अवरुद्ध करेगा, लेकिन लैम्ब्डा विधि को कॉल करने का वास्तविक कार्य एसिंक्रोनस है जब BeginInvoke के माध्यम से बुलाया जाता है। सिर्फ इसलिए कि कॉल अतुल्यकालिक है इसका मतलब यह नहीं है कि कॉल का नतीजा होगा। –

+0

@ जेफ: हाँ, यह सच है। मैं सुझाव देता हूं कि @ सिमॉन ने इसे और अधिक स्पष्ट करने के लिए अपने उत्तर में इस स्पष्टीकरण को शामिल किया है। – mafu

1

एक MessageBox.Show के लिए, प्रश्न ज्यादातर अप्रासंगिक है।

केवल अंतर यह है कि BeginInvoke साथ, ही ब्लॉक नहीं है, इसलिए यह कर बातें (सफाई, आगे की प्रक्रिया, आदि) जारी रख सकते हैं धागा बुला है।

यूआई थ्रेड स्पष्ट रूप से अवरुद्ध होगा, क्योंकि एक मॉडल विंडो पॉप अप करने के लिए उपयोगकर्ता इनपुट पर प्रतीक्षा कर रही है।

14

साइमन वास्तव में गलत नहीं है।

BeginInvoke यूआई थ्रेड को एक संदेश भेजने जैसा है और कह रहा है, "जैसे ही आपको मौका मिलता है, इसे करें।"

Invoke यह कहने जैसा है, "यह अभी करें। मैं इंतजार करूंगा।"

स्पष्टीकरण: सिर्फ इसलिए कि आप यूआई धागा कहता हूं, इसका मतलब यह नहीं है कि आप यूआई धागे के भगवान हैं और सब कुछ यह कर रहा है छोड़ने के लिए मजबूर कर सकते हैं यह "इस वक्त, करो"। असल में, उपरोक्त कथन में मुख्य शब्द "मैं इंतजार करूंगा।"

बात यह है कि, आपके उदाहरण कोड में, यूआई थ्रेड पर जो संदेश आप भेज रहे हैं वह है: MessageBox.Show पर कॉल करें। अंदाज़ा लगाओ? यह यूआई थ्रेड को किसी भी तरह से अवरुद्ध करने जा रहा है।

आप,, BeginInvoke की अतुल्यकालिक व्यवहार नोटिस यह एक अलग धागे से फोन अपने कोड में BeginInvoke कॉल के बाद एक ब्रेकप्वाइंट रखा, और नोटिस ब्रेकप्वाइंट हिट हो जाता है कि यहाँ तक कि जब संदेश बॉक्स प्रदर्शित होता है चाहते हैं (और यूआई अवरुद्ध है)। यदि आप Invoke पर कॉल करते हैं, तो कोड तब तक जारी नहीं रहेगा जब तक उपयोगकर्ता संदेश बॉक्स को खारिज नहीं कर देता।

+1

यह थोड़ी सी स्पष्टीकरण है जिसे मैं ढूंढ रहा था :) – mafu

+1

अच्छी व्याख्या। बस यह ध्यान रखना चाहता था कि दोनों BeginInvoke और इन दोनों को आमंत्रित करें "जैसे ही आपको मौका मिलता है, इसे करें।", लेकिन Invoke भी जोड़ता है "और जब तक आप पूरा नहीं कर लेते हैं तब तक मैं इंतजार करूंगा।" जैसा कि आपने सुझाव दिया है ("अभी यह करें") के साथ आने वाली चीज़ों को जल्दी से करने में सक्षम नहीं है। –

+0

@ एलन: हाँ, मुझे लगता है कि यह एक तरह का व्यक्तिपरक है कि आप उन शब्दों की व्याख्या कैसे करते हैं। बात यह है कि * वास्तविक * जीवन में, आप * ** ** ** ** कुछ नहीं कर सकते ** ** अभी ** ** - लेकिन आप उन्हें * अभी * इसे करने के लिए कह सकते हैं "और वहां खड़े हो जाओ अपनी बाहों को पार करते हुए, अपने पैर को तब तक टैप करते हैं जब तक कि उन्होंने वास्तव में इसे नहीं किया है। मेरे लिए, यह 'Invoke' का इरादा है - आप सही हैं कि ऐसा नहीं है कि आप इसे वर्तमान में निष्पादित करने वाले कोड को निरस्त करने के लिए मजबूर कर सकते हैं; लेकिन आप प्रभावी रूप से * कह रहे हैं * कम से कम, "अभी यह करें।" –

2

जबकि अधिकांश उत्तर तकनीकी रूप से सही हैं, वे स्पष्ट प्रश्न नहीं पूछते हैं।

आप अपने संदेश बॉक्स() कॉल को पहले स्थान पर Invoke/BeginOnvoke में क्यों लपेटना चाहते हैं?

जेफ ने समझाया, इस स्थिति में BeginInvoke या Invoke का उपयोग करने में कोई फायदा नहीं है।

ऐसा लगता है कि आप एक बहु-थ्रेडेड स्थिति में विंडोज़ फॉर्म/नियंत्रण पर Invoke/BeginInvoke का उपयोग करने और एक प्रतिनिधि उदाहरण (यानी Asynchornous प्रोग्रामिंग मॉडल) पर Invoke/BeginInvoke का उपयोग करने के बीच उलझन में हैं।

यह करना आसान है क्योंकि नाम स्पष्ट रूप से समान हैं, हालांकि परिदृश्य आप उनका उपयोग करेंगे और उनका व्यवहार अलग है।

पुस्तक CLR Via C# पुस्तक दोनों प्रकार के Invoke/BeginInvoke का एक अच्छा स्पष्टीकरण देता है।

संबंधित मुद्दे

 संबंधित मुद्दे