2009-12-15 9 views
16

ग्रीटिंग्स, मैं सी # में कुछ एप्लिकेशन विकसित कर रहा हूं। फिलहाल मैं थ्रेडिंग से निपट रहा हूं और मेरे पास एक सवाल है कि मेरे दिमाग में है। Invoke और BeginInvoke के बीच क्या अंतर है? मैं कुछ धागे पढ़ सकते हैं और मैं यहाँ कुछ उपयोगी जानकारी मिल: hereInvoke और BeginInvoke

हालांकि क्या निम्नलिखित कोड में आह्वान और BeginInvoke के बीच अंतर है:

private void ProcessRoutine() 
{ 
    for (int nValue = StartFrom; nValue <= EndTo; nValue++) 
    { 
     this.Invoke(this.MyDelegate, nValue); 
     //this.BeginInvoke(this.MyDelegate, nValue); 
    } 
    MessageBox.Show("Counting complete!"); 
} 
private void MessageHandler(int progress) 
{ 
    lblStatus.Text = lblStatus.Text = "Processing item: " + progress.ToString(); 
    progressBar1.Value = progress; 
} 

जहां MyDelegate MessageHandler कार्य करने के लिए एक संदर्भ है।

मैंने देखा कि BeginInvoke lblStatus.Text का उपयोग करके रीफ्रेश नहीं किया जाता है जहां Invoke का उपयोग लेबल को रीफ्रेश करता है। इसके अतिरिक्त मुझे पता है कि Invok इसके निष्पादन को पूरा करने के लिए इंतजार कर रहा है। सबसे महत्वपूर्ण मामला मुझे रूचि है कि इस मामले में ताज़ा लेबल टेक्स्ट में कोई अंतर क्यों है।

उत्तर

8

विधि के साथ विधि को निष्पादित किया जाता है और एप्लिकेशन इसे पूरा करने की प्रतीक्षा करता है।

BeginInvoke के साथ विधि को अनावश्यक रूप से लागू किया जाता है और एप्लिकेशन को निष्पादित करना जारी रहता है जबकि BeginInvoke में संदर्भित विधि निष्पादित की जाती है।

BeginInvoke के साथ आपको BeginInvnoke का उपयोग करके निष्पादित विधि के परिणाम प्राप्त करने के लिए एंडइवोक को कॉल करने की आवश्यकता है।

आपको BeginXXX विधियों में जीयूआई घटकों को अद्यतन नहीं करना चाहिए क्योंकि वे आपके आमंत्रण विधि के विपरीत, GUI थ्रेड में किसी अन्य थ्रेड में चलाए जाते हैं। आप GUI थ्रेड में एक अलग थ्रेड में जीयूआई घटकों तक नहीं पहुंच सकते हैं।

आशा है कि इससे मदद मिलती है!

+12

कॉलिंग BeginInvoke मतलब यह नहीं है यह यूआई पर निष्पादित नहीं कर रहा है धागा। इसका मतलब है कि इसे "इस" से जुड़े थ्रेड पर असीमित रूप से कहा जाता है जो यूआई थ्रेड हो सकता है। –

+0

इसलिए यदि यह किसी अन्य धागे में नहीं है, तो यह तब कैसे काम करता है? –

+8

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

1

BeginInvoke विधि निकाय को अन्य थ्रेड पर निष्पादित करता है और वर्तमान धागा को जारी रखने की अनुमति देता है। यदि आप किसी अन्य थ्रेड से नियंत्रण संपत्ति को सीधे अपडेट करने का प्रयास कर रहे हैं, तो यह अपवाद फेंक देगा।

+1

हाँ मैं जानता हूँ कि, लेकिन क्यों का उपयोग कर आह्वान मेरी लेबल पाठ ताजा है और BeginInvoke का उपयोग कर यह नहीं है –

+0

@Niao मेरा उत्तर के दूसरे वाक्य देख –

0

यह मूल रूप से नियंत्रण करता है कि आप नियंत्रण को सिंक्रनाइज़ या असीमित रूप से अपडेट करना चाहते हैं या नहीं। यह सब आपकी विशिष्ट स्थिति पर निर्भर करता है।

18

अपने लिंक से शुरू करने के लिए:

  • Control.Invoke: यूआई धागे पर कार्यान्वित करता है, लेकिन धागा बुला जारी रखने से पहले पूरा करने के लिए इंतजार कर रहा है।
  • Control.BeginInvoke: एसिंक्रोनस यूआई थ्रेड पर निष्पादन, और थ्रेड कॉलिंग पूर्ण होने की प्रतीक्षा नहीं करता है।

और MSDN से:

BeginInvoke धागा है कि नियंत्रण की अंतर्निहित संभाल पर बनाया गया था पर अतुल्यकालिक रूप से निर्दिष्ट प्रतिनिधि निष्पादित करता है।

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

वैकल्पिक रूप से, Invokeतुल्यकालिक है। टेक्स्ट बॉक्स अपडेट किया जाएगा क्योंकि कॉलिंग थ्रेड निरंतर निष्पादन से पहले कॉल को पूरा करने की प्रतीक्षा करेगा।

+2

एक मामूली बिंदु - विधि लौटने पर इसे निष्पादित नहीं किया जाता है, यह आग के रूप में किया जाता है और भूल जाता है - इसे COM/winapi ether –

+0

में निकाल दिया गया है आपकी प्रतिक्रिया के लिए धन्यवाद; मैंने अभी अपना जवाब अपडेट किया है। –

5

Control.BeginInvoke एक अलग धागे पर काम नहीं करता है (या ThreadPool), एक delegate.BeginInvoke करता है। MSDN के एक लाइनर का कहना है:

एसिंक्रोनस रूप से निर्दिष्ट प्रतिनिधि पर क्रियान्वित धागे पर कि नियंत्रण की अंतर्निहित संभाल पर बनाया गया था। कोई CLR Thread बनाई गई है -

हालांकि Control.BeginInvoke बस PostMessage और रिटर्न का उपयोग करता है।

PostMessage समारोह स्थानों (पोस्ट) संदेश कतार धागा कि धागा संदेश को संसाधित करने का इंतजार किए बिना निर्दिष्ट खिड़की और रिटर्न बनाया के साथ जुड़े में एक संदेश।

This article को सारांशित काफी अच्छी तरह से Invoke या BeginInvoke उपयोग करने के लिए है कि क्या:

उपयोग करने के लिए कार्य करते हैं कौन, आप से पूछना। यह वास्तव में आपकी आवश्यकता पर निर्भर करता है। यदि आगे बढ़ने से पहले आप अपना यूआई अपडेट पूरा करना चाहते हैं, तो आप Invoke का उपयोग करें। यदि ऐसी कोई आवश्यकता नहीं है, तो मैं BeginInvoke का उपयोग करने का सुझाव देता हूं, क्योंकि यह थ्रेड को "तेज" कहता है। हालांकि BeginInvoke के साथ कुछ गॉचा के हैं।

  • समारोह आप BeginInvoke के माध्यम से बुला रहे हैं साझा accesses तो राज्य (राज्य यूआई धागा और अन्य धागे के बीच साझा), आप मुसीबत में हैं। राज्य को उस समय के बीच बदल सकता है जब आपने BeginInvoke कहा था और जब लपेटा फ़ंक्शन वास्तव में निष्पादित होता है, जिससे समय की समस्याएं खोजने में कठिनाई होती है।
  • यदि आप BeginInvoke के माध्यम से फ़ंक्शन पर संदर्भ पैरामीटर पास कर रहे हैं, तो आपको सुनिश्चित करना होगा कि फ़ंक्शन पूर्ण होने से पहले कोई भी ऑब्जेक्ट को संशोधित नहीं करता है। आमतौर पर, लोग BeginInvoke, पर जाने से पहले ऑब्जेक्ट ऑब्जेक्ट क्लोन करते हैं जो पूरी तरह से समस्या से बचाता है।
संबंधित मुद्दे