2011-01-06 12 views
8

मैं प्रेषक के संदर्भ में थोड़ा उलझन में हूं। मान लें कि मैं पृष्ठभूमि थ्रेड पर कुछ प्रकार का लंबा ऑपरेशन कर रहा हूं। मैं यूई थ्रेड को अपडेट करना चाहता हूं, मुझे समझ में आता है कि मैं इसे प्रेषक के माध्यम से करता हूं। मेरा सवाल है, क्या मैं प्रेषक को स्थैतिक रूप से कॉल करता हूं: डिस्पैचर.बिनजिन इनवोक (mywork) ... या नियंत्रण पर मैं अपडेट करना चाहता हूं: mytextbox.Dispatcher.BeginInvoke (mywork)डब्ल्यूपीएफ/थ्रेडिंग: नियंत्रण पर प्रेषक स्थिर बनाम प्रेषक?

उत्तर

0

सबसे पहले मुझे लगता है कि यह समझना महत्वपूर्ण है , कि Dispatcher बड़े पृष्ठभूमि संचालन को संभालने के लिए डिज़ाइन नहीं किया गया है। यह किसी ऑब्जेक्ट के यूआई थ्रेड पर कतार बनाने के लिए डिज़ाइन किया गया है।

कह रही है कि Dispatcher.BeginInvoke विधि को लागू करने के लिए मानक तरीका नियंत्रण पर इसे कहते हैं होगा::

यहाँ नेट सूत्रण मॉडल और Dispatcher के बारे में एक सार्थक MSDN लेख है
startStopButton.Dispatcher.BeginInvoke(
    DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber) 
); 

आशा है कि मदद करता है!

14

यह ध्यान देने योग्य है कि फोन करने Dispatcher.BeginInvoke एक स्थिर कॉल नहीं है लायक है: यह एक अंतर्निहित this.Dispatcher.BeginInvoke है। यदि आप इस कॉल का उपयोग कर सकते हैं, तो संभवतः आप पहले से ही नियंत्रण या विंडो के भीतर अपना कोड लिख रहे हैं। उस स्थिति में, आप शायद को कॉल करने के लिए सुरक्षित हैं क्योंकि अधिकांश समय प्रति एप्लिकेशन एक यूआई थ्रेड होगा।

वास्तविक स्थिर कॉल Dispatcher.CurrentDispatcher.BeginInvoke होगा, जो कुछ नहीं है जिसे आप कॉल करना चाहते हैं (क्यों हसन खान के जवाब पर मेरी टिप्पणी देखें)।

संपादित करें:Application.Current.Dispatcher कॉलिंग नहीं एक बुरी बात है। (और, स्पष्टता के लिए, यह एक उदाहरण संपत्ति है, स्थिर नहीं - Application के स्थैतिक/सिंगलटन उदाहरण पर बुलाया जा रहा है।) यह संपत्ति डिस्पैचर को उस धागे के लिए वापस कर देगी जिसे ऐप बनाया गया था, और आम तौर पर यह थ्रेड है यूआई को भी बनाया गया है - इसलिए Application.Current.Dispatcher उसी डिस्पैचर को myWindow.Dispatcher के रूप में देता है।

स्थिर कॉल Dispatcher.CurrentDispatcher (जो मैंने चेतावनी दी है) उस थ्रेड के लिए एक प्रेषक देता है जिसे आप इसे कहते हैं। यदि आप इसे पृष्ठभूमि थ्रेड से कॉल करते हैं, तो आपको विशेष रूप से उस थ्रेड के लिए बनाया गया एक नया डिस्पैचर मिलेगा - जो अक्सर वांछित नहीं होता है।

+0

* क्यों * एप्लिकेशन.क्यूरेंट। डिस्पैचर 'का उपयोग एक बुरा विचार है? मैं इसे अब तक किसी भी समस्या के बिना अपने आवेदन में उपयोग करता हूं। इसकी आवश्यकता केवल 'आवेदन() के लिए है। चलाने के लिए चलाएं()। – Aphex

+0

@ एफेक्स: मैंने एक संपादन के रूप में जवाब दिया है क्योंकि मैं टिप्पणी में इसे फिट नहीं कर सकता - लेकिन 'एप्लिकेशन.क्यूरेंट। डिस्पैचर' के साथ कुछ भी गलत नहीं है (और मैंने यह नहीं कहा था कि वहां था)। 'Application.Current.Dispatcher' और' Dispatcher.CurrentDispatcher 'बहुत अलग व्यवहार करते हैं! –

+0

ऐसे मामले हैं जहां Application.Current.Dispatcher का उपयोग सुरक्षित नहीं है (हालांकि बहुत दुर्लभ), उदा। WinForms (या किसी भी अन्य गैर-WPF) ऐप में WPF नियंत्रण होस्ट करना (एप्लिकेशन.क्यूरेंट शून्य है) या एक ही ऐप के साथ कई UI-threads हैं (साझा ऐप संसाधनों के साथ बहुत सारी परेशानी हैं, लेकिन मामला अभी भी प्रासंगिक है)। इसलिए सबसे सुरक्षित तरीका नियंत्रण का उपयोग करना है। डिस्पैचर – Aloraman

0

जबकि सबसे का उपयोग कर मामलों में या तो DispatcherObject.Dispatcher, (सभी निर्भरता वस्तुओं और नियंत्रण अन्य लोगों के अलावा, DispatcherObject से विरासत) या Application.Current.Dispatcher करना सही बात है वहाँ आमतौर पर केवल एक यूआई धागा के रूप में, एक से अधिक यूआई धागे हो सकता है और अलग-अलग खिड़कियां अलग-अलग प्रेषकों का उपयोग कर सकती हैं। उस स्थिति में, अपने प्रेषक का उपयोग कर नियंत्रण को अपडेट करना महत्वपूर्ण है। यह संपत्ति में संग्रहीत है (DispatcherObject से विरासत में मिला), इस खिड़की और खिड़की में कोई अन्य नियंत्रण।

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