Invoke () और BeginInvoke () के बीच क्या अंतर है


398

बस सोच क्या बीच का अंतर BeginInvoke()और Invoke()कर रहे हैं?

मुख्य रूप से क्या प्रत्येक के लिए इस्तेमाल किया जाएगा।

EDIT: एक थ्रेडिंग ऑब्जेक्ट बनाने और उस पर कॉल आह्वान करने और केवल BeginInvoke()एक प्रतिनिधि को कॉल करने में क्या अंतर है ? या वे एक ही बात कर रहे हैं?

जवाबों:


568

क्या आपका मतलब है Delegate.Invoke/ BeginInvokeया Control.Invoke/ BeginInvoke?

  • Delegate.Invoke: समान रूप से, समान धागे पर निष्पादित करें।
  • Delegate.BeginInvoke: एक threadpoolधागे पर अतुल्यकालिक रूप से निष्पादित करें ।
  • Control.Invoke: UI थ्रेड पर निष्पादित होता है, लेकिन कॉलिंग थ्रेड जारी रखने से पहले पूरा होने की प्रतीक्षा करता है।
  • Control.BeginInvoke: UI थ्रेड पर निष्पादित होता है, और कॉलिंग थ्रेड पूरा होने की प्रतीक्षा नहीं करता है।

जब आप उपयोग करना चाह सकते हैं तो टिम के उत्तर का उल्लेख है BeginInvoke- हालांकि यह ज्यादातर की ओर देखा गया था Delegate.BeginInvoke, मुझे संदेह है।

Windows प्रपत्र एप्लिकेशन के लिए, मेरा सुझाव है कि आपको आमतौर पर उपयोग करना चाहिए BeginInvoke। इस तरह से आपको गतिरोध के बारे में चिंता करने की ज़रूरत नहीं है, उदाहरण के लिए - लेकिन आपको यह समझने की ज़रूरत है कि यूआई आपके द्वारा इसे देखने के समय तक अपडेट नहीं किया गया है! विशेष रूप से, आपको डेटा को संशोधित नहीं करना चाहिए जो यूआई थ्रेड प्रदर्शन उद्देश्यों के लिए उपयोग करने वाला हो सकता है। उदाहरण के लिए, यदि आप एक है, तो Personसाथ FirstNameऔर LastNameगुण, और तुमने किया था:

person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";

तब यूआई अच्छी तरह से "कीसर स्पेसी" प्रदर्शित कर सकता है। (वहाँ एक बाहर का मौका है यह "केविन सोज़" प्रदर्शित कर सकता है, लेकिन केवल मेमोरी मॉडल की अजीबता के माध्यम से।)

जब तक आपके पास इस प्रकार का मुद्दा है, हालांकि, Control.BeginInvokeसही प्राप्त करना आसान है, और आपके पृष्ठभूमि धागे को बिना किसी अच्छे कारण के इंतजार करने से बचाएगा। ध्यान दें कि विंडोज फॉर्म टीम ने गारंटी दी है कि आप Control.BeginInvoke"आग और भूल जाओ" तरीके से उपयोग कर सकते हैं - अर्थात बिना कॉल किए EndInvoke। यह सामान्य रूप से async कॉल के बारे में सच नहीं है: आम तौर पर हर BeginXXX में एक समान EndXXX कॉल होना चाहिए, आमतौर पर कॉलबैक में।


4
उसके बाद बीइंग इनवोक पर पीपीएल का उपयोग क्यों करेगा? इनवोक का उपयोग करने पर कुछ फायदे नहीं होने चाहिए। दोनों पृष्ठभूमि में प्रक्रियाओं को निष्पादित करते हैं, बस एक ही धागे पर है, दूसरे अलग धागे पर?
यिन

2
@Jon: जबकि मैं Dispatcher.BeginInvoke का उपयोग कर रहा हूं, मेरा कोड ठीक काम कर रहा है और Dispatcher.Invoke में मेरे एप्लिकेशन को कुछ सेकंड के लिए प्रतीक्षा कर रहा है, तो यह सभी नियंत्रणों को शुरू करने के बाद शुरू करता है, क्या आप मुझे यह पता लगाने में मदद कर सकते हैं कि मैं वास्तव में किस स्थान पर फंस गया हूं ?
शार्पब्रेन

6
@SharpUrBrain: Control.BeginInvoke, Dispatcher.BeginInvoke के बराबर की तरह है, लेकिन WinForms के लिए (जबकि Dispatcher WPF और सिल्वरलाइट के लिए है)।
जॉन स्कीट

4
@SharpUrBrain: मैं आपको सुझाव देना चाहूंगा कि आप टिप्पणियों में जारी रखने के बजाय एक विशिष्ट प्रश्न पूछें - और निश्चित रूप से जांचें कि क्या वही प्रश्न पहले किसी और ने पहले पूछा है।
जॉन स्कीट

2
@AZ: हां, "यूआई थ्रेड पर" का अर्थ है वह विशेष "यूआई थ्रेड" पर है जो उस विशेष नियंत्रण के हैंडल का मालिक है। आमतौर पर, केवल एक UI थ्रेड होता है, लेकिन कई UI थ्रेड्स होना संभव है, और उन्नत अनुप्रयोगों में ऐसे कारण हैं कि आप उन्हें क्यों चाहते हैं। तकनीकी रूप से, कोई भी (सामान्य?) धागा यूआई संदेश पंप शुरू कर सकता है और यूआई धागा बन सकता है - और बाद में संदेश पंप बंद कर सकता है और अब यूआई धागा नहीं हो सकता है। (मुझे लगता है कि एक थ्रेडपूल धागा पर कोशिश करने के लिए कुछ नहीं है, हालांकि।)
रोब पार्कर

46

जॉन स्कीट के उत्तर पर निर्माण, ऐसे समय होते हैं जब आप एक प्रतिनिधि को आमंत्रित करना चाहते हैं और वर्तमान धागा जारी होने से पहले इसके निष्पादन के लिए इंतजार करना चाहते हैं। उन मामलों में चालान कॉल जो आप चाहते हैं।

बहु-थ्रेडिंग अनुप्रयोगों में, आप निष्पादन समाप्त करने के लिए किसी प्रतिनिधि पर प्रतीक्षा करने के लिए एक थ्रेड नहीं चाहते हैं, खासकर यदि वह प्रतिनिधि I / O करता है (जो प्रतिनिधि और आपके थ्रेड ब्लॉक बना सकता है)।

उन मामलों में BeginInvoke उपयोगी होगा। इसे कॉल करके, आप प्रतिनिधि को शुरू करने के लिए कह रहे हैं लेकिन फिर आपका धागा प्रतिनिधि के साथ अन्य चीजों को करने के लिए स्वतंत्र है।

BeginInvoke का उपयोग करने से आपके कोड की जटिलता बढ़ जाती है, लेकिन ऐसे समय होते हैं जब बेहतर प्रदर्शन जटिलता के लायक होता है।


27

Control.Invoke()और के बीच का अंतर Control.BeginInvoke()है,

  • BeginInvoke()GUI थ्रेड पर एसिंक्रोनस कार्रवाई शेड्यूल करेगा। जब एसिंक्रोनस कार्रवाई निर्धारित होती है, तो आपका कोड जारी रहता है। कुछ समय बाद (आपको ठीक से पता नहीं है कि) आपकी अतुल्यकालिक कार्रवाई को कब अंजाम दिया जाएगा
  • Invoke() आपकी एसिंक्रोनस क्रिया (GUI थ्रेड पर) निष्पादित करेगा और तब तक प्रतीक्षा करेगा जब तक आपकी कार्रवाई पूरी नहीं हो जाती।

एक तार्किक निष्कर्ष यह है कि जिस प्रतिनिधि को आप पास करते Invoke()हैं, उसके आउट-पैरामीटर या रिटर्न-वैल्यू हो सकते हैं, जबकि आप जिस प्रतिनिधि को पास करते BeginInvoke()हैं (परिणाम प्राप्त करने के लिए आपको EndInvoke का उपयोग करना होगा)।


20

बस उनके अंतर के प्रभाव को देखने के लिए एक छोटा, काम करने का उदाहरण देना है

new Thread(foo).Start();

private void foo()
{
  this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (ThreadStart)delegate()
    {
        myTextBox.Text = "bing";
        Thread.Sleep(TimeSpan.FromSeconds(3));
    });
  MessageBox.Show("done");
}

यदि StartInvoke का उपयोग करते हैं , तो टेक्स्ट अपडेट के लिए MessageBox पॉप एक साथ होता है। यदि 3 सेकंड की नींद के बाद इनवोक , मैसेजबॉक्स पॉप का उपयोग करें । इसलिए, एक एसिंक्रोनस ( BeginInvoke ) और एक सिंक्रोनस ( इनवोक ) कॉल के प्रभाव को दिखा रहा है ।


9

डेलिगेट.बेगिन इंवोक () एसिंक्रोनस रूप से एक प्रतिनिधि की कॉल को कतार में रखता है और तुरंत नियंत्रण लौटाता है। Delegate.BeginInvoke () का उपयोग करते समय, आपको परिणाम प्राप्त करने के लिए कॉलबैक विधि में Delegate.EndInvoke () को कॉल करना चाहिए।

डेलिगेट.इनवोक () समान रूप से प्रतिनिधि को एक ही थ्रेड में कॉल करता है।

MSDN आलेख


8

सिर्फ Invoke का उपयोग क्यों और कब करना है ()।

दोनों आह्वान () और BeginInvoke () डिस्पैचर थ्रेड को निर्दिष्ट कोड को मार्शल करें।

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

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

C # अध्याय 31 में प्रो WPF देखें

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