2010-01-05 13 views
5

मैंने पहले से ही फोरम की खोज की है लेकिन मुझे लगता है कि कोई समस्या नहीं है मेरी समस्या के लिए उपयुक्त है ...BackgroundWorker_RunWorker क्यों लागू नहीं हुआ GUI अपडेट नहीं किया गया है?

मैं एक बहुत समय लेने वाला ऑपरेशन संभालने के लिए पृष्ठभूमिवर्कर का उपयोग करता हूं। इस ऑपरेशन के बाद एक बटन को सक्षम करने के लिए सेट किया जाना चाहिए ताकि उपयोगकर्ता एक और ऑपरेशन कर सके।

मैं WPF का उपयोग कर रहा हूं और मैं एमवीवीएम पैटर्न का पालन कर रहा हूं, इसलिए मेरे पास इस बटन तक कोई सीधी पहुंच नहीं है। मुझे BackgroundWorker_RunWorker पूर्ण ईवेंट हैंडलर में एक विधि कॉल करना है जो एक प्रॉपर्टी सेट करता है, बटन को सक्षम-स्टेटस का प्रतिनिधित्व करता है, सच में।

यह सब एक चीज़ को छोड़कर ठीक काम करता है: बटन को केवल उदाहरण के बाद फिर से खींचा जाता है विंडो में क्लिक करें (या विंडो को अधिकतम करें, ...)। बहुत कष्टप्रद है और मुझे पूरा दिन ले लिया यही इस व्यवहार से छुटकारा पाने के, लेकिन मैं एक समाधान नहीं मिल सकता है ...

BackgroundWorker_RunWorkerCompleted ईवेंट हैंडलर इस तरह दिखता है:

void fileLoadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
     SetButtonToEnabled(); } 

किसी को भी किसी भी विचार कैसे है इस मुद्दे को ठीक करने के लिए?

संपादित करें:

बटन एक आदेश के लिए बाध्य है: के रूप में स्मिथ ने अपने ब्लॉग (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx) में कहा गया है

<Button Name="btnLoadTargetFile" Command="{Binding Path=LoadTargetCommand}" .../> 

यह आदेश एक RelayCommand है और इस तरह दिखता है:

public RelayCommand LoadTargetCommand 
    { 
     get 
     { 
      if (loadTargetCommand == null) 
      { 
       loadTargetCommand = new RelayCommand(param => this.OnRequestLoadFile(BusinessLogic.CustomTypes.TreeType.Target), param => this.CanLoadTarget); 
      } 
      return loadTargetCommand; 
     } 
     set { loadTargetCommand = value; } 
    } 

यह। CanLoadTarget को SetButtonToEnabled() द्वारा सत्य पर सेट किया गया है; विधि

संपादित करें 2:

निम्नलिखित कोड 'काम करता है':

fileLoadBackgroundWorker.RunWorkerAsync(argumentList); 
while(fileLoadBackgroundWorker.IsBusy) 
    System.Windows.Forms.Application.DoEvents(); 
SetButtonToEnabled(); 

लेकिन वह वास्तव में खतरनाक और बदसूरत कोड के कुछ प्रकार है ...

+0

जब आप संपत्ति को सत्य पर सेट करते हैं तो क्या आप 'प्रॉपर्टी चेंज' ईवेंट बढ़ाते हैं (यानी क्या आपका व्यूमोडेल लागू होता है 'INotifyPropertyChanged' सही ढंग से)? –

+0

अगर मैं फ़ाइल के बाद उस विधि को कॉल करता हूं LoadBackgroundWorker.RunWorkerAsync() सब कुछ ठीक काम करता है, तो मुझे नहीं लगता कि यह समस्या है ?! – lakai

+0

जिज्ञासा से बाहर, क्या आप फॉर्म के आकार या सीमा (सीमा रंग, आदि) में किसी भी WMI संशोधन का उपयोग कर रहे हैं? –

उत्तर

2

हालांकि यह does not आपकी समस्या को समझाने, आप अपने SetButtonToEnabled समारोह कॉल के अंत करने के लिए

System.Windows.Forms.Application.DoEvents(); 

या

Dispatcher.Invoke(new Action(delegate { }), DispatcherPriority.Background); 

जोड़ने के लिए (आप बटन सच करने के लिए सक्षम सेट करने के बाद) की कोशिश कर सकते। ऐसा लगता है कि पृष्ठभूमि कार्यकर्ता पूरी घटना को बुला रहा है, लेकिन जीयूआई ताज़ा नहीं है।

Here WPF में पृष्ठभूमि कार्यकर्ता का उपयोग करके एक पूर्ण उदाहरण है। आप इसे देख सकते हैं और यह सुनिश्चित कर सकते हैं कि आप सामान समान दिखें।

आप Asynchronous Threading with Background Worker Object पर भी एक नज़र डाल सकते हैं। यह डिस्पैचर और बैकग्राउंडर

WPF Threading Model का उपयोग करने का एक और शानदार स्रोत है, इसका उपयोग करने का एक अच्छा उदाहरण है।

+0

आपकी टिप्पणी के लिए धन्यवाद! मेरा कोड उदाहरण की तरह दिखता है सिवाय इसके कि मेरे पास – lakai

+0

का उपयोग करने वाले एमवीवीएम पैटर्न के कारण बटनों की सीधी पहुंच नहीं है, क्या आप SetButtonToEnabled के लिए कोड पोस्ट कर सकते हैं। मुझे पृष्ठभूमि कार्यकर्ता के साथ कोई समस्या नहीं है, क्योंकि आपने उल्लेख किया है कि पूर्ण को कॉल किया जाता है। यह शायद आप मुख्य धागे पर कर रहे हैं। पृष्ठभूमि में प्रक्रिया चल रही है, जबकि आप क्या कर रहे हैं? – SwDevMan81

+1

आप अमान्यateRequery सुझाए गए सुझावों को देखना चाहेंगे: http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx इसे सेटबटन ToEnabled – SwDevMan81

1

आपकी समस्या शायद कुछ भी नहीं किया है BackgroundWorker के साथ करो। यदि आप सीधे मुख्य धागे से SetButtonToEnabled विधि को कॉल करते हैं तो आप शायद वही व्यवहार देखेंगे। इस परीक्षण के लिए कॉल को RunWorkerAsync पर एक से SetButtonToEnabled पर बदलें।

कुछ टिप्पणीकारों ने सुझाव दिया कि आप अपने INotifyPropertyChanged कार्यान्वयन को अच्छी सलाह की तरह देखते हैं।

+0

धन्यवाद का उपयोग शुरू करने से पहले सब ठीक काम किया है! अगर मैं मुख्य थ्रेड में SetButtonToEnabled को कॉल करता हूं तो सब ठीक काम करता है ... – lakai

+0

क्या आप पुष्टि कर सकते हैं कि RunWorker पूर्ण घटना उठाई जा रही है? क्या आपके द्वारा सेट किया गया ब्रेकपॉइंट हिट हो जाता है? –

+0

हां यह करता है, ब्रेकपॉइंट हिट हो जाता है – lakai

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