दिलचस्प पोस्ट
किसी एप्लिकेशन को स्थापना रद्द करने से कैसे रोकें? डुप्लिकेट वैल्यू को पायथन में एक सूची में पहचानें आईओएस प्रीफ़िक्स.pch सर्वोत्तम अभ्यास जावा: एक स्ट्रिंग में एक मैच की स्थिति पाने के लिए विधि? क्लाइंट के क्लिपबोर्ड पर jQuery का उपयोग करके कॉपी कैसे करें? एंड्रॉइड क्लासनोटफ़ाउंड अपवाद यूनिट परीक्षणों के अंदर कोड क्यों नहीं बंडल संसाधन मिल सकता है? URL का अंतिम सेगमेंट पायथन कक्षाओं में हम __init__ का उपयोग क्यों करते हैं? ग्रहण शुरू नहीं होगा और मैंने कुछ भी नहीं बदला है शब्दकोश करने के लिए Linq क्वेरी परिणाम कनवर्ट करें Nodejs प्रतिक्रिया में फ़ाइल भेजें Xcode में आईओएस iPhone ऐप के साथ वॉचकिट ऐप को डिप्लेइंग (अक्षम) रोकें एन की गणना करने के लिए तेज़ तरीका! आधुनिक एम जहां एम प्रमुख है? फ़्लेक्सबॉक्स बटन या फ़ील्ड्स तत्वों पर काम नहीं कर रहा है

क्रॉस थ्रेड घटनाओं को आमंत्रित करने का सबसे सुरक्षित तरीका

मुझे पता है कि .नेट इवेंट मॉडल ऐसी है कि मैं अक्सर एक थ्रेड पर कोई ईवेंट तैयार कर रहा हूं और दूसरे धागे पर इसे सुन रहा हूं। मैं सोच रहा था कि एक पृष्ठभूमि धागा से एक घटना को मेरी UI थ्रेड पर मार्शल करने का सबसे साफ तरीका क्या है।

समुदाय सुझावों के आधार पर, मैंने इसका उपयोग किया है:

// earlier in the code mCoolObject.CoolEvent+= new CoolObjectEventHandler(mCoolObject_CoolEvent); // then private void mCoolObject_CoolEvent(object sender, CoolObjectEventArgs args) { if (InvokeRequired) { CoolObjectEventHandler cb = new CoolObjectEventHandler( mCoolObject_CoolEvent); Invoke(cb, new object[] { sender, args }); return; } // do the dirty work of my method here } 

वेब के समाधान से एकत्रित समाधान "क्रॉस थ्रेड घटनाओं को आमंत्रित करने का सबसे सुरक्षित तरीका"

कुछ अवलोकन:

  • साधारण प्रतिनिधियों को स्पष्ट रूप से कोड में न बनाएं, जब तक कि आप पूर्व-2.0 न हो, ताकि आप इसका उपयोग कर सकें:
  BeginInvoke(new EventHandler<CoolObjectEventArgs>(mCoolObject_CoolEvent), sender, args); 
  • इसके अलावा आपको ऑब्जेक्ट सरणी को बनाने और पॉप्युलेट करने की आवश्यकता नहीं है क्योंकि एल्ग्स पैरामीटर एक "पैरामीटर" प्रकार है, ताकि आप सूची में बस पास कर सकें।

  • मैं शायद Invoke पर BeginInvoke करना चाहता हूं क्योंकि बाद के कोड को असिंक्रोनस के रूप में बुलाया जाएगा जो हो सकता है या हो सकता है कि आप उसके बाद क्या नहीं हो लेकिन बाद के अपवादों को कॉल करने के बिना प्रचार करने में कठिनाई कर सकते हैं। क्या होगा कि आपका ऐप एक TargetInvocationException को समाप्त कर देगा।

मेरे पास इस ऑनलाइन के लिए कुछ कोड है यह अन्य सुझावों की तुलना में बहुत अच्छा है; निश्चित रूप से इसे बाहर की जाँच करें

नमूना उपयोग:

 private void mCoolObject_CoolEvent(object sender, CoolObjectEventArgs args) { // You could use "() =>" in place of "delegate"; it's a style choice. this.Invoke(delegate { // Do the dirty work of my method here. }); } 

मैं अनावश्यक प्रतिनिधि घोषणाओं से दूर हूं।

 private void mCoolObject_CoolEvent(object sender, CoolObjectEventArgs args) { if (InvokeRequired) { Invoke(new Action<object, CoolObjectEventArgs>(mCoolObject_CoolEvent), sender, args); return; } // do the dirty work of my method here } 

गैर-घटनाओं के लिए, आप System.Windows.Forms.MethodInvoker प्रतिनिधि या System.Action उपयोग कर सकते हैं।

संपादित करें: इसके अतिरिक्त, प्रत्येक घटना के अनुरूप EventHandler प्रतिनिधि हैं, इसलिए एक को फिर से इकट्ठा करने की कोई आवश्यकता नहीं है।

मुझे लगता है कि स्वच्छ तरीके से एओपी मार्ग जाना निश्चित रूप से है। कुछ पहलुओं को बनायें, आवश्यक विशेषताओं को जोड़ दें, और आपको कभी भी दोबारा संबंधों की जांच नहीं करनी होगी।

एक दिलचस्प पक्ष नोट के रूप में, WPF के बाध्यकारी हैंडल्स स्वचालित रूप से मार्शल करते हैं, ताकि आप UI को बाइंडिंग गुणों को ऑब्जेक्ट कर सकें जो कि पृष्ठभूमि थ्रेड्स पर विशेष रूप से किए बिना खास कुछ किए गए हैं। यह मेरे लिए एक महान टाइमवेर साबित हुआ है

एक्सएएमएल में:

 <TextBox Text="{Binding Path=Name}"/> 

मैंने अपने स्वयं के उद्देश्य के लिए निम्नलिखित 'सार्वभौमिक' क्रॉस थ्रेड कॉल वर्ग बनाया है, लेकिन मुझे लगता है कि इसे साझा करने के लायक है:

 using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace CrossThreadCalls { public static class clsCrossThreadCalls { private delegate void SetAnyPropertyCallBack(Control c, string Property, object Value); public static void SetAnyProperty(Control c, string Property, object Value) { if (c.GetType().GetProperty(Property) != null) { //The given property exists if (c.InvokeRequired) { SetAnyPropertyCallBack d = new SetAnyPropertyCallBack(SetAnyProperty); c.BeginInvoke(d, c, Property, Value); } else { c.GetType().GetProperty(Property).SetValue(c, Value, null); } } } private delegate void SetTextPropertyCallBack(Control c, string Value); public static void SetTextProperty(Control c, string Value) { if (c.InvokeRequired) { SetTextPropertyCallBack d = new SetTextPropertyCallBack(SetTextProperty); c.BeginInvoke(d, c, Value); } else { c.Text = Value; } } } 

और आप बस एक और धागा से SetAnyProperty () का उपयोग कर सकते हैं:

 CrossThreadCalls.clsCrossThreadCalls.SetAnyProperty(lb_Speed, "Text", KvaserCanReader.GetSpeed.ToString()); 

इस उदाहरण में उपरोक्त KvaserCanReader वर्ग अपना स्वयं का थ्रेड चलाता है और मुख्य प्रपत्र पर lb_Speed ​​लेबल की टेक्स्ट प्रॉपर्टी सेट करने के लिए कॉल करता है।

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

  #region SyncContextCancel private SynchronizationContext _syncContextCancel; /// <summary> /// Gets the synchronization context used for UI-related operations. /// </summary> /// <value>The synchronization context.</value> protected SynchronizationContext SyncContextCancel { get { return _syncContextCancel; } } #endregion //SyncContextCancel public void CancelCurrentDbCommand() { _syncContextCancel = SynchronizationContext.Current; //ThreadPool.QueueUserWorkItem(CancelWork, null); Thread worker = new Thread(new ThreadStart(CancelWork)); worker.Priority = ThreadPriority.Highest; worker.Start(); } SQLiteConnection _connection; private void CancelWork()//object state { bool success = false; try { if (_connection != null) { log.Debug("call cancel"); _connection.Cancel(); log.Debug("cancel complete"); _connection.Close(); log.Debug("close complete"); success = true; log.Debug("long running query cancelled" + DateTime.Now.ToLongTimeString()); } } catch (Exception ex) { log.Error(ex.Message, ex); } SyncContextCancel.Send(CancelCompleted, new object[] { success }); } public void CancelCompleted(object state) { object[] args = (object[])state; bool success = (bool)args[0]; if (success) { log.Debug("long running query cancelled" + DateTime.Now.ToLongTimeString()); } } 

आप किसी सामान्य प्रकार के एक घटक को विकसित करने का प्रयास कर सकते हैं जो एक सिंक्रनाइज़ेशन कंटैन्टेक्ट को इनपुट के रूप में स्वीकार करता है और इवेंट्स को खोलने के लिए उसका उपयोग करता है।

मुझे हमेशा आश्चर्य है कि यह हमेशा कितना महंगा है यह मानना ​​है कि आह्वान की आवश्यकता है …

 private void OnCoolEvent(CoolObjectEventArgs e) { BeginInvoke((o,e) => /*do work here*/,this, e); }