2009-07-28 14 views
9

मैं सी # और डब्ल्यूपीएफ में काम कर रहा हूं, दोनों के लिए बहुत नया है।व्यस्त लूप के दौरान मैं प्रगति कैसे प्रदर्शित करूं?

मेरे पास एक लूप है जो बाहरी स्रोत से बहुत सारे डेटा को पढ़ता है। प्रक्रिया में लगभग 20 सेकंड लगते हैं, और मैं उपयोगकर्ता को प्रगति दिखाना चाहता हूं। मुझे किसी भी फैंसी प्रोग्रेस बार की आवश्यकता नहीं है, इसलिए मैंने अपनी प्रगति को एक लेबल में प्लॉट करना चुना है जो "चरण 1/1000" कहेंगे, फिर "चरण 2/1000" आदि में बदलें।

मेरा कोड कुछ ऐसा दिखता है यह:

// "count" is the number of steps in the loop, 
// I receive it in previous code 

String countLabel = "/"+count.ToString(); 

for (i = 0; i < count; i++) 
{ 
    ... do analysis ... 
    labelProgress.Content = "Step "+i.ToString()+countLabel 
} 

हालांकि, उस विश्लेषण के दौरान स्क्रीन "अटक गई" है और प्रगति आगे बढ़ने के रूप में दिखाई नहीं देती है। मैं अपने अतीत से सी ++ में इस व्यवहार को समझता हूं, जहां मेरे पास लूप से अधिसूचनाएं प्राप्त करने वाली प्रगति पट्टी, या पेंट/रीफ्रेश के कुछ रूप, या अपनी संदेश कतार को संसाधित करने के लिए विंडो/ऐप को मजबूर करने के लिए एक अलग थ्रेड होगा।

सी # में ऐसा करने का सही तरीका क्या है? मैं लेबल से बंधा नहीं कर रहा हूँ, इसलिए अगर एक सरल प्रगति-बार पॉपअप स्क्रीन मैं इस लेबल यह भी बहुत अच्छा होगा के बजाय इस्तेमाल कर सकते हैं ...

धन्यवाद

+0

यह आप के लिए मदद की जा सकती है , ** 100% परीक्षण ** http://stackoverflow.com/a/42995210/6863414 –

उत्तर

11

एक BackgroundWorker को काम ले जाएँ और ReportProgress विधि का उपयोग करें।);

for (i = 0; i < count; i++) 
{ 
    ... do analysis ... 
    worker.ReportProgress((100 * i)/count); 
} 

private void MyWorker_ProgressChanged(object sender, 
    ProgressChangedEventArgs e) 
{ 
    taskProgressBar.Value = Math.Min(e.ProgressPercentage, 100); 
} 
+0

क्या वह थ्रेड-सुरक्षित है? –

+1

हां, यह होना चाहिए। आपका पृष्ठभूमि कार्यकर्ता केवल एक थ्रेड में है, प्रगति बार अद्यतन केवल यूआई थ्रेड पर है। UI थ्रेड के अलावा कोई भी थ्रेड एक अपवाद फेंक देगा यदि यह मान को अपडेट करने का प्रयास करता है। तो आप इस विधि के साथ थ्रेड सुरक्षा की गारंटी है। – user7116

2

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

हमारे लिए भाग्यशाली, वहाँ हर WPF नियंत्रण आप एक और प्राथमिकता के साथ एक नया धागा ऊपर आग देता है कि पर एक डिस्पैचर संपत्ति है ..

labelProgress.Dispatcher.Invoke(DispatcherPriority.Background, 
        () => labelProgress.Content = string.Format("Step {0}{1}", i, countLabel)); 

यह आग ऊपर पृष्ठभूमि में एक धागा और काम मिलेगा किया हुआ! तुम भी अन्य DispatcherPriority विकल्पों की कोशिश कर सकते

पी एस मैं भी एक गुमनाम विधि जोड़कर उसे कुछ हद तक पार्स करने .. आप कोई आपत्ति नहीं है उम्मीद अपने स्ट्रिंग ठीक करने के लिए स्वतंत्रता ले लिया ..

3
//Create a Delegate to update your status button 
    delegate void StringParameterDelegate(string value); 
    String countLabel = "/" + count.ToString(); 
    //When your button is clicked to process the loops, start a thread for process the loops 
    public void StartProcessingButtonClick(object sender, EventArgs e) 
    { 
     Thread queryRunningThread = new Thread(new ThreadStart(ProcessLoop)); 
     queryRunningThread.Name = "ProcessLoop"; 
     queryRunningThread.IsBackground = true; 
     queryRunningThread.Start(); 
    } 

    private void ProcessLoop() 
    { 
     for (i = 0; i < count; i++) 
     { 
      ... do analysis ... 
      UpdateProgressLabel("Step "+i.ToString()+countLabel); 
     } 
    } 

    void UpdateProgressLabel(string value) 
    { 
     if (InvokeRequired) 
     { 
      // We're not in the UI thread, so we need to call BeginInvoke 
      BeginInvoke(new StringParameterDelegate(UpdateProgressLabel), new object[] { value }); 
      return; 
     } 
     // Must be on the UI thread if we've got this far 
     labelProgress.Content = value; 
    } 
+0

पृष्ठभूमिवर्कर प्रदान किया जाता है ताकि आपको धागे से बाहर निकलने की सभी गड़बड़ी को संभालने की आवश्यकता न हो। – user7116

+0

@sixlettervariables इस विधि का मान यह है कि यह आपको कॉलर को केवल एक पूर्णांक को पार करने की तुलना में अधिक लचीलापन देता है - आप कुछ भी कर सकते हैं (जैसे स्टेटस संदेश वापस पास करना, उदाहरण के लिए) – ean5533

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