2011-10-20 11 views
16

का उपयोग कर मैं चैट क्लाइंट का निर्माण कर रहा हूं और dispatcher का उपयोग करने के तरीके पर 100% सुनिश्चित नहीं हूं।सी # डिस्पैचर

public void LostConnection() 
{ 
    myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); 
} 

मैं एक Dispatcher.Invoke साथ (myGUI.chatBox...) भीतर बयान surrond करने की आवश्यकता है: तो सवाल मैं इस तरह के रूप में एक विधि है? मैं किसी भी मदद की सराहना करता हूं।

+0

कि निर्भर करता है ... उस विधि पर कौन सा धागा चलता है? इसके अलावा, बस सुनिश्चित करने के लिए, आप WPF का उपयोग कर रहे हैं, है ना? ('डिस्पैचर 'केवल उसके साथ काम करता है।) – svick

+1

आप किस यूआई ढांचे का उपयोग कर रहे हैं?(WinForms, WPF, या SL) उनके बीच अंतर हैं –

+0

हाँ, जैसे कि svick सुझाता है, यह इस बात पर निर्भर करता है कि आप अपने यूआई को किसी अन्य थ्रेड (असीमित रूप से) – gideon

उत्तर

68

आपके ऐप के लिए मुख्य यूआई धागा (आमतौर पर ManagedThreadId==1) है। आम तौर पर चैट ऐप में आपकी घटनाएं अन्य धागे (या तो समर्पित सॉकेट सुनो धागे या थ्रेड पूल धागे सुनना कोड से आती हैं) पर आती हैं। यदि आप किसी अन्य थ्रेड पर खींचने वाली किसी ईवेंट से UI को अपडेट करना चाहते हैं तो आपको प्रेषक का उपयोग करना होगा। यहां एक उपयोगी परीक्षण Dispatcher.CheckAccess() विधि है जो कोड को यूआई थ्रेड पर सही करता है और कुछ अन्य धागे पर गलत होता है।

using System.Windows.Threading; // For Dispatcher. 

if (Application.Current.Dispatcher.CheckAccess()) { 
    network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
} 
else { 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{ 
     network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
    })); 
} 

आप मुख्य विंडो में हैं, तो आप उपयोग कर सकते हैं:

Dispatcher.BeginInvoke(... 

आप someother संदर्भ में हैं, तो एक दृश्य मॉडल जैसे तो का उपयोग करें: एक ठेठ कॉल कुछ की तरह लग रहा

Application.Current.Dispatcher.BeginInvoke( 

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

MessageBox, प्रेषक और आह्वान/BeginInvoke:
Dispatcher.Invoke अपने धागा जब तक MessageBox खारिज किया जाता है रोकेंगे।
Dispatcher.BeginInvoke आपके थ्रेड कोड को निष्पादित करने की अनुमति देगा जबकि यूआई थ्रेड संदेश बॉक्स कॉल पर अवरुद्ध होने तक अवरुद्ध होगा।

वर्तमान डिस्पैचर बनाम वर्तमान। डिस्पैचर!
Dispatcher.CurrentDispatcher के बर्तन बनें क्योंकि मेरी समझ यह है कि वर्तमान धागे के लिए एक डिस्पैचर वापस यूआई थ्रेड नहीं होगा। आम तौर पर आप यूआई थ्रेड पर प्रेषक में दिलचस्पी रखते हैं - Application.Current.Dispatcher हमेशा यह लौटाता है।

अतिरिक्त ध्यान दें:
आप पा रहे हैं, तो आप प्रेषक की जाँच करने के CheckAccess अक्सर तो एक उपयोगी सहायक विधि है कर रहे हैं:

public void DispatchIfNecessary(Action action) { 
    if (!Dispatcher.CheckAccess()) 
     Dispatcher.Invoke(action); 
    else 
     action.Invoke(); 
} 

कौन सा कहा जा सकता है के रूप में:

DispatchIfNecessary(() => { 
    network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
}); 
+0

अरे दोस्तों, क्षमा करें मैंने निर्दिष्ट नहीं किया है, हाँ यह एक wpf एप्लिकेशन है और हाँ यह क्रॉस थ्रेडिंग है। मैं बैकएंड में प्रतिनिधि को स्थापित कर रहा हूं जो उसके मॉडल को अलर्ट करता है जो तब उस प्रेषक विधि को कॉल करेगा और गुई इंटरफेस को अपडेट करेगा। मुझे अभी भी एक प्रेषक जोड़ने के लिए इंटेलिजेंस के साथ एक विकल्प नहीं मिल रहा है, लेकिन मैं इसे मजबूर करने की कोशिश करूंगा और देख सकता हूं कि यह चलता है या नहीं। धन्यवाद दोस्तों! कोई अन्य सुझाव? – Tombo890

+0

यदि आपने कथन का उपयोग करके शामिल किया है और Application.Current.Dispatcher का उपयोग करना है तो आपको परिणाम मिलना चाहिए। यदि आपका "बैकएंड" एक डीएल में है तो आपको यूआई थ्रेड डिस्पैचर को अपनी ऑब्जेक्ट में पास करने की आवश्यकता होगी ताकि यह इसका संदर्भ दे सके। – Ricibob

+0

@ रिसीबोब, बस नाइटपीकी होने के लिए, मुझे लगता है कि यूआई थ्रेड में हमेशा आईडी का आईडी नहीं होना चाहिए। – svick

2

कुछ इस तरह (मेरे सिर के ऊपर से) काम करना चाहिए:

public void LostConnection() 
{ 
    myGUI.Invoke 
     ((MethodInvoker)delegate 
    { 
     myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); 
    }); 
} 
+0

वह WinForms में होगा। यह सवाल स्पष्ट रूप से डब्ल्यूपीएफ के बारे में है। – svick

+1

हाँ। यह सवाल से स्पष्ट नहीं था। –

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