2012-10-17 20 views
10

विनफॉर्म में, सभी नियंत्रणों में InvokeRequired प्रॉपर्टी होती है, जो मुझे कॉल करने के लिए सही होती है। [प्रारंभ करें] इसे संशोधित करने के लिए नियंत्रण पर शामिल हों।Dispatcher का सही उपयोग (या उपयोग नहीं)।)

WPF में, वहाँ DispatcherObject.CheckAccess() और Dispatcher.CheckAccess() में एक जाहिरा तौर पर इसी तरह के निर्माण है, लेकिन मैं EditorBrowsable(EditorBrowsableState.Never) विशेषता के आधार पर भयभीत हूँ। जब मैं इस तरह के संपादक ब्राउज़िंग को अक्षम करता हूं, तो इसका मतलब यह है कि "आपको ऐसा नहीं करना चाहिए। नहीं, वास्तव में। यदि यह आवश्यक है तो अपनी तत्काल समस्या का समाधान करें, आपने अपनी अत्यधिक समस्या के समाधान को गलत तरीके से डिज़ाइन किया है।" दूसरी ओर, मुझे मिला एकमात्र विकल्प (और, वास्तव में, मेरा मूल समाधान) Thread.CurrentThread.ManagedThreadId == 1 है। (हालांकि यह भयानक है। और इसके सामान्य मामले में काम नहीं करता। मुझे पता है। यह मेरी सीमित उपयोग के लिए काम करता है।)

MSDNdocumentation की उपस्थिति और EditorBrowsable विशेषता के पीछे तर्क पर खामोश है। क्या इसका वास्तव में मतलब है "इसका उपयोग न करें", जैसा कि मैंने लिखा होगा, या क्या इसका कुछ और कम निषिद्ध अर्थ है?

+0

एमएसएफटी के कुछ लोगों ने इस पोस्ट में जवाब दिया था। http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bd0e6f6c-cadd-48f1-8e1a-163c2f17e4ca/ लगता है कि 'EditorBrowsableState.Advanced' अधिक उपयुक्त हो सकता है, लेकिन ऐसा प्रतीत नहीं होता है किसी भी तकनीकी कारण के रूप में इसे क्यों नहीं कहा जाना चाहिए (कम से कम उस धागे से)। – keyboardP

उत्तर

15

WPF में, आप Dispatcher.Invoke परवाह किए बिना अपने वर्तमान धागे की कॉल कर सकते हैं, और यह तदनुसार कॉल संभाल लेंगे - अगर आप सही धागा कगार पर हैं, यह सिर्फ अपने कोड को लागू कर देंगे, और यह CheckAccess का उपयोग करता है संभाल करने के लिए यह व्यवहार

BeginInvoke के लिए जो धागा आप वर्तमान में चालू हैं, वह अप्रासंगिक है: BeginInvoke हमेशा असुरक्षित है, और निष्पादन का आदेश प्रेषक की कतार में आपके द्वारा जोड़े गए आइटम की प्राथमिकता पर निर्भर है।

यदि आपको विधि का उपयोग नहीं करना था, तो यह सार्वजनिक नहीं होगा: उस विशेषता का इरादा केवल इंटेलिजेंस और अन्य संपादक-ब्राउज़र जैसे तंत्र से छिपाने के लिए है। आपको आम तौर पर Dispatcher.CheckAccess() का उपयोग करने की आवश्यकता नहीं है, शायद यही कारण है कि इसे गैर-ब्राउज़ करने योग्य के रूप में चिह्नित किया गया है, लेकिन इसका ज्ञान कुछ ऐसा है जिसे हम केवल अनुमान लगा सकते हैं (जब तक एरिक लिपर्ट नहीं देख रहा है ;-)

सारांश में: बस Dispatcher.Invoke पर कॉल करें और CheckAccess पर चिंता न करें।

+2

मुझे लगता है कि उपयोग करने के लिए निर्धारित करने के लिए थ्रेड पहुंच की जांच करने के लिए योग्यता है। चेकएप के आधार पर स्पष्ट नियंत्रण या विशिष्ट पूर्वापेक्षाएँ करने से कुछ मामलों में समझदारी होती है। लेकिन इसकी आदत बनाना बुरा है, क्योंकि यह सिर्फ प्रयासों को डुप्लिकेट करेगा। हालांकि स्पष्ट रूप से बोलते हुए, Dispatcher.cs मैंने कभी देखा है सबसे गड़बड़ .NET कक्षाओं में से एक है। – erodewald

+0

इसका एकमात्र नकारात्मक पक्ष यह है कि आपको यह याद रखने के लिए मजबूर होना पड़ता है कि कौन सी विधियां यूआई को अपडेट कर सकती हैं और हमेशा उन्हें कॉल करते समय 'Invoke()' का उपयोग करती हैं, क्योंकि एक विधि के अंदर चेक/इनवॉक के विपरीत यह गारंटी देता है कि यह हमेशा चिंता किए बिना काम करता है इसके बारे में – Basic

+0

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

0

मैं जोड़ना होगा: अगर आप mimick करना चाहते हैं "If invokeRequired then ..."
मैं कहूंगा: का उपयोग नहीं करते "if Dispatcher.CheckAccess" इसके बजाय, उपयोग:

If Me.Dispatcher.Thread Is System.Threading.Thread.CurrentThread Then 
    Label1.Content = value 
Else 
    Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value) 
    Return 
End If 


मुद्दा रहा था कि CheckAccess हमेशा सच था, के बाद भी आह्वान शुरू ...

कोई बात नहीं थी, निम्नलिखित कोड भी ठीक काम करता है:

If Me.Dispatcher.CheckAccess Then 
    Label1.Content = value 
    Else 
    Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value) 
    Return 
End If 
संबंधित मुद्दे