दिलचस्प पोस्ट
विकल्प टैग के साथ छवियां जोड़ना पायथन प्रोग्राम को सी / सी ++ कन्वर्ट करने के लिए? SQL सर्वर में सबसे छोटा अप्रयुक्त नंबर ढूंढें डिजिटल फाइलों पर हस्ताक्षर करें नोडजे में धागे कैसे बनाएं वसंत एमवीसी: सत्यापन कैसे करें? जावा में getPath (), getAbsolutePath (), और getCanonicalPath () के बीच क्या अंतर है? जावा का उपयोग कर सेलेनियम वेबड्राइवर में एक ड्रॉपडाउन मूल्य का चयन कैसे करें जावास्क्रिप्ट चर में पृष्ठभूमि का रंग हेक्स कैसे printf / sprintf में तर्कों की चर संख्या पारित करने के लिए वर्तमान दिनांक पास करना जेएस को गणित करने के लिए मजबूर कैसे करें, इसके बजाय दो स्ट्रिंग को एक साथ रखा जाए मैं एक ही ईवेंट हैंडलर के लिए कई बटन कैसे सब्सक्राइब कर सकता हूं और किस बटन पर क्लिक किया गया था इसके अनुसार कार्य किया जा सकता है? मैं नए PostgreSQL JSON डेटाटाइप के अंदर फ़ील्ड कैसे संशोधित करूं? घुमाओ पर एक छवि स्पिन या घुमाएं

आह्वान (प्रतिनिधि)

क्या कोई इस कथन पर लिखित इस बयान की व्याख्या कर सकता है

Invoke(Delegate): 

नियंत्रण की अंतर्निहित विंडो हैंडल के मालिक के पास थ्रेड पर निर्दिष्ट प्रतिनिधि को निष्पादित करता है

क्या कोई यह समझा सकता है कि इसका अर्थ क्या है (विशेष रूप से बोल्ड) मैं इसे स्पष्ट रूप से प्राप्त करने में सक्षम नहीं हूं

वेब के समाधान से एकत्रित समाधान "आह्वान (प्रतिनिधि)"

इस सवाल का जवाब यह है कि कैसे सी # नियंत्रण काम करता है

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

Control.InvokeRequired से

प्रभावी रूप से, जो शामिल है वह यह सुनिश्चित करता है कि आप जिस कोड को बुला रहे हैं, वह थ्रेड पर होता है कि नियंत्रण "पर रहता है" प्रभावी ढंग से क्रॉस थ्रेडेड अपवादों को रोकता है

एक ऐतिहासिक परिप्रेक्ष्य से, नेट 1.1 में, यह वास्तव में अनुमति दी गई थी। इसका क्या मतलब यह है कि आप किसी भी पृष्ठभूमि थ्रेड से "जीयूआई" धागे पर कोड को आज़मा सकते हैं और निष्पादित कर सकते हैं और यह ज्यादातर काम करेगा कभी-कभी यह आपके ऐप को बाहर निकलने का कारण बनता है क्योंकि आप जीयूआई धागा को प्रभावी ढंग से हस्तक्षेप कर रहे थे जबकि यह कुछ और कर रहा था यह क्रॉस थ्रेडेड अपवाद है – एक पाठ बॉक्स अपडेट करने की कोशिश कीजिए जबकि जीयूआई कुछ और चित्र कर रहा है

  • कौन सी कार्रवाई प्राथमिकता लेती है?
  • क्या यह दोनों संभवतः एक बार में होने के लिए संभव है?
  • जीयूआई को चलाए जाने वाले अन्य सभी आदेशों का क्या होता है?

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

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

यह वास्तव में " संदेश पम्प क्या है " प्रश्न में पहले से ही उत्तर दिया गया है और नियंत्रणों के साथ बातचीत करते समय वास्तविक तंत्र को समझने के लिए पढ़ने की सिफारिश की जाती है

अन्य पढ़ने में आपको उपयोगी मिल सकती है:

शुरुआती मांगों के साथ क्या हो रहा है

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

और, एक प्रतिनिधि नमूने के साथ अधिक कोड भारी अवलोकन के लिए:

अमान्य क्रॉस-थ्रेड संचालन

 // the canonical form (C# consumer) public delegate void ControlStringConsumer(Control control, string text); // defines a delegate type public void SetText(Control control, string text) { if (control.InvokeRequired) { control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text}); // invoking itself } else { control.Text=text; // the "functional part", executing only on the main thread } } 

एक बार जब आप InvokeRequired के लिए सराहना करते हैं, तो आप इन कॉल को लपेटने के लिए एक एक्सटेंशन विधि का उपयोग करने पर विचार कर सकते हैं। यह अटैक ओवरफ्लो प्रश्न में शामिल है, जो अपनाने की आवश्यकता के साथ स्वीकृत कोड को साफ कर रहा है ।

ऐतिहासिक रूप से क्या हुआ, इसके बारे में एक और लिखना भी है जो ब्याज की हो सकती है।

विंडोज फॉर्म में एक नियंत्रण या खिड़की ऑब्जेक्ट एक हैंडल (कभी-कभी एचडब्ल्यूएनडी कहा जाता है) द्वारा पहचानी जाने वाली एक Win32 विंडो के आस-पास एक आवरण है। नियंत्रण के साथ आपके द्वारा किए जाने वाली अधिकांश चीजें अंततः एक Win32 API कॉल हो सकती हैं जो इस हैंडल का उपयोग करती हैं। संभाल उस धागे के स्वामित्व में है जो इसे बनाया (आमतौर पर मुख्य धागा), और किसी दूसरे धागे द्वारा हेरफेर नहीं किया जाना चाहिए। यदि किसी कारण के लिए आपको किसी अन्य धागा से नियंत्रण के साथ कुछ करने की आवश्यकता है, तो आप मुख्य धागा से अपनी ओर से करने के लिए पूछने के लिए Invoke कर सकते हैं।

उदाहरण के लिए, यदि आप वर्कर थ्रेड से एक लेबल के पाठ को बदलना चाहते हैं, तो आप ऐसा कुछ कर सकते हैं:

 theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!")); 

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

नीचे नमूना thread1 में एक अपवाद फेंकता है क्योंकि SetText1 textBox1 को संशोधित करने का प्रयास कर रहा है। लेकिन थ्रेड 2 में, SetText2 में क्रिया को थ्रेड में क्रियान्वित किया जाता है जिसमें पाठ बॉक्स बनाया गया था

 private void btn_Click(object sender, EvenetArgs e) { var thread1 = new Thread(SetText1); var thread2 = new Thread(SetText2); thread1.Start(); thread2.Start(); } private void SetText1() { textBox1.Text = "Test"; } private void SetText2() { textBox1.Invoke(new Action(() => textBox1.Text = "Test")); } 

आमंत्रित ((MethodInvoker) प्रतिनिधि {textBox1.Text = "test";});

व्यावहारिक रूप से इसका मतलब है कि प्रतिनिधि को मुख्य थ्रेड पर लागू होने की गारंटी है। यह महत्वपूर्ण है क्योंकि खिड़कियों के नियंत्रण के मामले में यदि आप मुख्य धागे पर अपनी संपत्ति अपडेट नहीं करते हैं तो आप या तो परिवर्तन नहीं देखते हैं, या नियंत्रण अपवाद उठाता है।

पैटर्न है:

 void OnEvent(object sender, EventArgs e) { if (this.InvokeRequired) { this.Invoke(() => this.OnEvent(sender, e); return; } // do stuff (now you know you are on the main thread) } 

इसका अर्थ है कि प्रतिनिधि UI थ्रेड पर चलेगा, भले ही आप उस पद्धति को किसी पृष्ठभूमि कार्यकर्ता या धागे-पूल थ्रेड से कहते हों। यूआई तत्वों का धागा आकर्षण है – वे केवल सीधे एक धागे से बात कर रहे हैं: UI थ्रेड। यूआई थ्रेड को धागा के रूप में परिभाषित किया गया है जो नियंत्रण उदाहरण बनाया है, और इसलिए विंडो हैंडल के साथ जुड़ा हुआ है लेकिन यह सब एक कार्यान्वयन विवरण है।

मुख्य बिंदु यह है: आप इस पद्धति को एक कार्यकर्ता धागे से कहते हैं ताकि आप UI (एक लेबल, आदि में मूल्य बदलने के लिए) का उपयोग कर सकें – चूंकि आपको UI थ्रेड से किसी अन्य थ्रेड से ऐसा करने की अनुमति नहीं है

this.Invoke(delegate) सुनिश्चित करें कि आप इस प्रतिनिधि को तर्क के लिए बुला रहे हैं। मुख्य थ्रेड / बनाये गये धागे पर this.Invoke() को this.Invoke()

मैं कह सकता हूं कि मुख्य थ्रेड को छोड़कर एक थंब नियम आपके फ़ॉर्म नियंत्रणों तक नहीं पहुंचता है।

हो सकता है कि निम्न पंक्तियां इनवॉक् करें () का उपयोग करने के लिए समझें

  private void SetText(string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } } 

हालाँकि हालाँकि आप थ्रेडपूल थ्रेड बनाते हैं (यानी कार्यकर्ता धागा) यह मुख्य थ्रेड पर चलाएगा। यह एक नया धागा नहीं बनाया जाएगा coz मुख्य धागा आगे निर्देशों के प्रसंस्करण के लिए उपलब्ध है। तो पहले जांच करें कि वर्तमान चल रहा धागा इस का उपयोग कर मुख्य थ्रेड है। this.InvokeRequired यदि रिटर्न सही होता है तो वर्तमान कोड वर्कर थ्रेड पर चल रहा है, इसलिए इसे कॉल करें। इन्वोक (डी, न्यू ऑब्जेक्ट [] {टेक्स्ट});

और सीधे यूआई कंट्रोल का अद्यतन करें (यहां आपको गारंटी दी जाती है कि आप मुख्य थ्रेड पर कोड चला रहे हैं।)

प्रतिनिधि, अनिवार्य रूप से इनलाइन Action या Func<T> आप एक प्रतिनिधि को एक विधि के दायरे के बाहर घोषित कर सकते हैं जो आप चल रहे हैं या lambda अभिव्यक्ति ( => ) का प्रयोग कर रहे हैं; क्योंकि आप एक विधि के भीतर प्रतिनिधि को चलाते हैं, तो आप इसे थ्रेड पर चलाते हैं जो चालू विंडो / एप्लिकेशन के लिए चलाया जा रहा है जो बोल्ड में बिट है।

Lambda उदाहरण

 int AddFiveToNumber(int number) { var d = (int i => i + 5); d.Invoke(number); } 

इसका मतलब है कि आपके द्वारा पारित किए गए प्रतिनिधि को थ्रेड पर निष्पादित किया जाता है जो नियंत्रण ऑब्जेक्ट (जो UI थ्रेड है) को बनाया है।

आपको इस पद्धति को कॉल करने की ज़रूरत होती है जब आपका आवेदन बहु-थ्रेडेड होता है और आप UI थ्रेड के अलावा किसी थ्रेड से कुछ यूआई ऑपरेशन करना चाहते हैं, क्योंकि अगर आप किसी अलग धागा से किसी नियंत्रण पर कोई विधि कॉल करने का प्रयास करते हैं तो आपको एक मिलेगा System.InvalidOperationException।