2010-02-05 11 views
6

मेरे पास एक भूगर्भ मानचित्र वाला एक प्रोग्राम है जिसमें एम्बेडेड है। नक्शा के लिए इवेंट हैंडलिंग नक्शा को उत्तरदायी रखने के लिए एक अलग धागे पर संभाला जाता है (उदाहरण के लिए, मानचित्र पर क्लिक होने पर आग लगने वाली घटनाएं)।सी #, डब्ल्यूपीएफ, स्वचालित रूप से डिस्पैचर को कॉल करें। आवश्यकता होने पर इन्वोक करें?

समस्या यह है कि जब मैप एक घटना को चलाता है, तो मेरे प्रोग्राम को इसकी चीजों में कुछ चीजों को अपडेट करने की आवश्यकता होती है, और मानचित्र पर चित्रों को संभालने के लिए मानचित्र में वापस कॉल करने की आवश्यकता होती है।

मैंने इस में पूरे ईवेंट हैंडलर विधि को लपेटने की कोशिश की। डिस्पैचर.इनवोक, जो मुझे मुख्य यूआई थ्रेड पर वापस रखता है। यह मेरे जीयूआई को अपडेट करने के लिए बहुत अच्छा काम करता है, लेकिन जब मैं मानचित्र में वापस कॉल करता हूं, तो भी मैं यूआई थ्रेड पर हूं जो मानचित्र में कुछ समस्याएं पैदा कर सकता है।

असल में, इस काम को करने के लिए, मुझे हर बार dispatcher.invoke चलाने की आवश्यकता होगी जब मैं अपने गुई पर नियंत्रण बदलना चाहता हूं। क्या dispatcher.invoke में प्रत्येक कॉल को लपेटने के बिना मैं इसे स्वचालित रूप से कर सकता हूं? मुझे उम्मीद है कि यह सब समझ में आता है।

यहाँ घटना के बारे में मैं बात कर रहा हूँ के लिए कुछ उदाहरण कोड ..

private void Map_OnMapClicked(object sender, MapClickedEventArgs e) 
    { 
     this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => 
     { 
      // Do something to update my gui 
     })); 

     Map.DoSomethingInTheMap(); 

     this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => 
     { 
      // Do something to update my gui 
     })); 


     //etc etc etc 
    } 

उत्तर

6

आप अपने स्वयं के तुल्यकालन संदर्भ में प्रत्येक संबंधित आपरेशन रखने की जरूरत है, तो यह दुर्भाग्य से सबसे अच्छा तरीका है। जब भी आप अपना जीयूआई अपडेट करते हैं तो आपको डिस्पैचर का उपयोग करके आमंत्रित करने की आवश्यकता होगी।

  1. अपने जीयूआई संचालन बैच के लिए प्रयास करें:

    यहाँ बनाने यह आसान के लिए कुछ सुझाव हैं। कम कोड की आवश्यकता के अलावा (कम आह्वान कॉल के माध्यम से), आपको बेहतर प्रदर्शन मिलेगा। प्रत्येक डिस्पैचर। इनवोक कॉल में उचित ओवरहेड होता है, क्योंकि यह डिस्पैचर की संदेश कतार में एक संदेश पोस्ट करता है जिसे संसाधित किया जाना चाहिए।

  2. अवरोधक से बचने के लिए Dispatcher.BeginInvoke का उपयोग करने पर विचार करें, जब तक कि आपको वास्तव में प्रतीक्षा करने की आवश्यकता न हो।

  3. आप नेट 4 (या आरएक्स फ्रेमवर्क में 3.5sp1 को backport) से कार्य समानांतर लाइब्रेरी का उपयोग कर सकते हैं, तो आप Task instances synchronized to the GUI thread उपयोग करने के लिए इस दोबारा काम पर विचार करना चाहते हो सकता है। FromCurrentSynchronizationContext का उपयोग करके एक कार्य शेड्यूलर बनाकर, आप डिस्पैचर आमंत्रण कॉल की तुलना में जीयूआई पर चलाने के लिए कार्यों को शेड्यूल कर सकते हैं। यह आपको बैचिंग पर कुछ नियंत्रण भी दे सकता है, क्योंकि आप उन्हें शेड्यूल कर सकते हैं, और आवश्यकतानुसार ब्लॉक/प्रतीक्षा कर सकते हैं।

2

आप PostSharp की तरह कुछ का उपयोग करें या करने के लिए एक प्रणाली को बुलाती है, जहां आप एक बार नारा है और बहुत कुछ कर अपने यूआई अद्यतन गाढ़ा करने के लिए कोशिश कर सकते। या यहां तक ​​कि इस तरह का एक पैटर्न (यह विनफॉर्म है लेकिन विचार समान है):

private void UpdateToolStripItemText(ToolStripItem toolStripItem, string text) 
{ 
    if (InvokeRequired) 
    { 
     Invoke(new UpdateToolStripItemTextDelegate(UpdateToolStripItemText), new object[] { toolStripItem, text }); 
    } 
    else 
    { 
     if (text != null) 
     { 
      toolStripItem.Text = text; 
     } 
    } 
} 
संबंधित मुद्दे

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