2012-05-04 19 views
62

Dispatcher.CurrentDispatcher (System.Windows.Threading में) और Application.Current.Dispatcher (System.Windows में) के बीच अंतर क्या हैं?Dispatcher.CurrentDispatcher बनाम आवेदन। वर्तमान। डिस्पैचर

मेरे पेट मुझसे कहता है कि Application.Current.Dispatcher कभी नहीं बदलेगा और, वर्तमान आवेदन में सभी धागे को वैश्विक है, जबकि Dispatcher.CurrentDispatcher धागा जिसमें से यह कहा जाता था पर निर्भर करता है Dispatcher का एक नया उदाहरण बना सकते हैं।

क्या यह सही है?

यदि यह है, तो मुख्य रूप से बहु-थ्रेडेड यूआई के लिए Dispatcher.CurrentDispatcher का उद्देश्य है?

उत्तर

74

मेरे पेट मुझसे कहता है कि Application.Current.Dispatcher कभी नहीं बदलेगा और वर्तमान आवेदन में सभी धागे को वैश्विक है, जबकि Dispatcher.CurrentDispatcher धागा पर निर्भर करता है डिस्पैचर का एक नया उदाहरण बना सकते हैं जिसमें से यह कहा जाता था।

यह सही है।

इसके अतिरिक्त, गैर-यूआई थ्रेड से Dispatcher.CurrentDispatcher तक पहुंचने में कोई भी बात नहीं है। यह तब तक कुछ नहीं करेगा जब तक कि आप Dispatcher.Run पर कॉल न करें, और अनंत संदेश लूप में जाकर वह कार्यकर्ता धागे के भीतर से नहीं करना चाहते हैं।

तो:

  • सबसे आम स्थिति में, जहां आपका ऐप्स केवल एक ही यूआई धागा, Application.Current.Dispatcher और Dispatcher.CurrentDispatcher यूआई धागा के भीतर से ही उदाहरण वापस आ जाएगी है में। आप जो भी उपयोग करते हैं वह वरीयता का मामला है।

  • यदि आपके ऐप में एक से अधिक यूआई थ्रेड हैं तो प्रत्येक DispatcherObject होगा जो यूआई थ्रेड के प्रेषक के साथ स्थायी रूप से जुड़ा हुआ है जो इसे निर्माण पर बनाया गया था। इस मामले में, Application.Current.Dispatcher आपके आवेदन के धागे के प्रेषक को संदर्भित करेगा; आप अपने अन्य यूआई थ्रेड्स के स्वामित्व वाले नियंत्रणों को संदेश पोस्ट करने के लिए इसका उपयोग नहीं कर पाएंगे।

+1

स्पष्टीकरण के लिए धन्यवाद, लेकिन इसका मतलब क्या है "यह तब तक कुछ नहीं करेगा जब तक कि आप डिस्पैचर.रुन को कॉल न करें"? मैंने एक गैर-यूआई थ्रेड से CurrentDispatcher का उपयोग किया है, और Invoke वास्तव में एक प्रतिनिधि को आह्वान करता है। क्या आपका मतलब है कि प्रतिनिधियों को बस कॉलिंग थ्रेड पर बुलाया जाएगा? – ken

+2

@ken: 'Invoke' और दोस्तों को सामान्य रूप से "पैकेज" (मार्शल, अगर आप पसंद करते हैं) एक Win32 संदेश में एक विधि कॉल करें और इसे एक संदेश कतार में पोस्ट करें जिससे संदेश लूप (प्रेषक लूप) अंततः इसे निष्कर्ष निकालता है और निष्पादित करता है कहते हैं। चूंकि कोई प्रेषक लूप नहीं है (यदि आप उस लूप में थे * आपका * कोड नहीं चल रहा होगा) कॉल वास्तव में कभी नहीं होगा। तो मुझे लगता है कि 'Invoke' पहले चेक करता है यदि आप पहले से ही' CurrentDispatcher' थ्रेड में ऑप्टिमाइज़ेशन के रूप में हैं और यदि आप मार्शलिंग के बजाय स्पॉट पर कॉल निष्पादित कर रहे हैं। आप 'Thread.ManagedThreadId' को चेक करके इसे सत्यापित कर सकते हैं। – Jon

+0

* आप अपने अन्य यूआई थ्रेड्स के स्वामित्व वाले नियंत्रणों पर संदेशों को पोस्ट करने के लिए इसका उपयोग नहीं कर पाएंगे। * तो, आपके औसत WPF एप्लिकेशन में कितने यूआई थ्रेड हैं? – Will

8

मेरे पेट मुझसे कहता है कि Application.Current.Dispatcher कभी नहीं बदलेगा और, वर्तमान आवेदन में सभी धागे को वैश्विक है, जबकि Dispatcher.CurrentDispatcher धागा जिसमें से यह कहा जाता था पर निर्भर करता है डिस्पैचर का एक नया उदाहरण बना सकते हैं ।

यह सही है, Application.Current.Dispatcher वर्तमान थ्रेड के प्रेषक होने के लिए निर्माण पर असाइन किए गए एप्लिकेशन की एक उदाहरण संपत्ति है। और Dispatcher.CurrentDispatcher के प्रलेखन बताते हैं:

धागा वर्तमान में क्रियान्वित करने के लिए डिस्पैचर हो जाता है और अगर एक पहले से ही धागा साथ संबद्ध नहीं है एक नया डिस्पैचर पैदा करता है।


अगर ऐसा है, Dispatcher.CurrentDispatcher के प्रयोजन के मल्टी-थ्रेडेड यूआई के लिए मुख्य रूप से है?

संभवतः, मुझे बैकग्राउंड थ्रेड के प्रेषक को प्राप्त करने में कोई भी उपयोग नहीं हुआ है क्योंकि आपके पास आमतौर पर उन यूआई-एल्मेंट्स नहीं हैं जिनके लिए आप संचालन भेजना चाहते हैं।

16

यह बस में कहें ...

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

Application.Current.Dispatcher हमेशा आपको यूआई थ्रेड का प्रेषक देगा, क्योंकि यह थ्रेड है जो एकमात्र एप्लिकेशन इंस्टेंस को स्पिन करता है।