2016-12-14 13 views
5

मेरे पास पृष्ठभूमिवर्कर और एक एकल प्रोग्रेसबार है। काम करते समय, पृष्ठभूमिवर्कर एक ट्रिपल फॉर-लूप के माध्यम से चलता है और प्रोग्रेसबार में प्रगति की रिपोर्ट करता है।मैं नेस्टेड लूप (प्रगति पट्टी के लिए) में एकाधिक चर के आधार पर प्रगति की रिपोर्ट कैसे कर सकता हूं?

वर्तमान में, रिपोर्ट की जा रही प्रगति केवल बाहरी-लूप (xProgress) की है, जो काम करती है, लेकिन आसानी से नहीं चलती है। लक्ष्य प्रोग्रेसबार के लिए आंतरिक लूप के प्रगति प्रतिशत के लिए भी जिम्मेदार है, ताकि प्रोग्रेसबार अधिक आसानी से और अधिक सटीक अपडेट हो सके।

DoWork विधि:

private void bgw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int xMax, yMax, zMax; 

     xMax = 10; 
     for (int x = 1; x <= xMax; x++) 
     { 
      yMax = 5; 
      for (int y = 1; y <= yMax; y++) 
      { 
       zMax = new Random().Next(50, 100); 
       for (int z = 1; z <= zMax; z++) 
       { 
        Thread.Sleep(5); /// The process 

        double xProgress = (double)x/(double)xMax; 
        double yProgress = (double)y/(double)yMax; 
        double zProgress = (double)z/(double)zMax; 

        /// The progress calculation: 
        double progressCalc = xProgress; 

        int progress = (int)(progressCalc * pgb.Maximum); 

        bgw.ReportProgress(progress); 
       } 
      } 
     } 
    } 
+0

जब एक 'y-loop' 100% पर है, तो आप के बारे में' बढ़ाने के लिए 1 से x', तो आप कह सकते हैं '100% y' एक' 1% x' है, और z और y के लिए ही कर रहे हैं । तो 'वर prog = XPROG + yProg * 0.01d * xmax + zProg * 0.01d * yMax * 0.01d * xMax' (या * ऐसा ही कुछ *)। आप * हो सकता है * छोरों 'max' को' को अधिकतम-1' के बजाय 1 0 से जा रहा यह सही ढंग से गणना करने के लिए के लिए प्राप्त करने के लिए है, लेकिन मैं, यकीन नहीं है तो आप इसे जांच होनी चाहिए। – SimpleVar

+0

दुर्भाग्य से, की स्थापना 'कि सूत्र के progressCalc' वजह से अंतिम परिणाम 1.00d, जो ProgressBar से ऊपर जाने का कारण बना पार करने के लिए। – DomTheDeveloper

+0

मैंने आपको बताया था कि आपको इसकी जांच करनी चाहिए। क्या आप 0 से अधिकतम -1 तक जा रहे हैं? – SimpleVar

उत्तर

3

यह काम करता है, भले ही आप पहले से अपने सबसे अच्छे/सबसे खराब स्थिति पता नहीं है। अधिकतम में से कोई भी zMax के समान रूप में यादृच्छिक हो सकता है।

static void F() 
{ 
    var r = new Random(); 
    int xMax = 10; 
    int yMax = 5; 
    int zMax; 

    for (int x = 0; x < xMax; x++) 
    { 
     double xProg = (double)x/xMax; 

     for (int y = 0; y < yMax; y++) 
     { 
      double yProg = (double)y/(yMax * xMax); 

      zMax = r.Next(50, 100); 
      for (int z = 0; z < zMax; z++) 
      { 
       double zProg = (double)z/(zMax * yMax * xMax); 

       var prog = xProg + yProg + zProg; 

       Console.WriteLine(prog.ToString("P")); 
       // bgw.ReportProgress((int)(prog * pgb.Maximum)); 
      } 
     } 
    } 

    Console.WriteLine(1.ToString("P")); // Make sure to report the final 100% 
    // bgw.ReportProgress((int)pgb.Maximum); 
} 

Btw, मैं 1 साथ pgb.Maximum की जगह ले चाहते हैं और OnProgressHandler में इसके द्वारा प्रगति गुणा। इस तरह थ्रेडेड विधि यूआई तत्वों को बिल्कुल स्पर्श नहीं करती है।

1

अपडेट किया गया उत्तर:

के बाद से भीतरी पाश आप तय कर सकता है यह कितने कदम अग्रिम चाहिए पुनरावृत्तियों की संख्या ज्ञात नहीं है। उदाहरण 10

तब के लिए आप कुछ इस तरह कर सकता है:

progressbarMaximum = xMax * yMax * 10 

सही z लूप इससे पहले कि आप 10 अपने z-पाश की जांच में साथ Zmax विभाजित करके zModulo मिलता है

zMax % zModulo == 0 

फिर प्रगति पट्टी बढ़ाएं।

पुराना जवाब:

आप xmax, yMax और Zmax गुणा यदि आप अंतरतम लूप के पुनरावृत्तियों की कुल संख्या मिलता है।

उस मूल्य पर अधिकतम प्रगतिबार सेट करें।

आंतरिक लूप वृद्धि प्रगति पट्टी के प्रत्येक पुनरावृत्ति पर।

+0

दुर्भाग्यवश, कोड में दिखाए गए अनुसार, प्रत्येक वाई के लिए zMax बदलता है। तो, मुझे नहीं पता कि पुनरावृत्तियों की कुल संख्या में जा रहा है। – DomTheDeveloper

0

आप नहीं कर सकते हैं। इस बारे में सोचें - क्या होगा यदि पहले रैंडम सभी 50 थे और आप पहले से ही 2 बाहरी लूपों में से आधा कर चुके हैं - यदि शेष रैंडम 50 होंगे - आपने 50% किया है। यदि शेष रैंडम 100 होंगे - आप केवल 33% ही करेंगे। तो आप नहीं जानते कि प्रगति पट्टी कितनी दूर होनी चाहिए।

(बेशक यादृच्छिक परिणाम आम तौर पर उस तरह नहीं होगा। यह सिर्फ बिंदु को वर्णन। है)

3

यह सच है कि आप नहीं जानते कि आपके लूप कितने पुनरावृत्तियों को करेंगे, लेकिन आप निश्चित रूप से अपने प्रगति संकेतक को सुगम बना सकते हैं।

मान लें कि सबसे खराब मामले में आपका कुल पुनरावृत्ति xMax * yMax * worstZMax है।

worstZMax = 99 क्योंकि ऊपरी बाध्य सबसे खराब स्थिति में Random.Next(minValue:int, maxValue:int)

इसलिए कुल पुनरावृत्तियों में अनन्य है 5 * 10 * 99 = 4950 हो जाएगा।

अब हम है कि कुल के साथ शुरू और इसे समायोजित के रूप में आवश्यक हम एक y पाश के लिए Zmax पैदा करने के बाद पुनरावृत्तियों ढीला जब और हम प्रभावी रूप से प्रगति गणना और रिपोर्टिंग चिकनी सकें।

यह कैसे मैं यह कर होता है:

private void bgw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    const int xMax = 10; 
    const int yMax = 5; 
    const int worstZMax = 99; //because upper is exclusive in Random.Next(lower, upper) 

    var iteration = 0; 
    var total = xMax * yMax * worstZMax; //total number of iterations (worst case) 

    for (var x = 1; x <= xMax; x++) 
    { 
     for (var y = 1; y <= yMax; y++) 
     { 
      var zMax = new Random().Next(50, 100); 

      //get how many iterations did we miss, and adjust the total iterations 
      total -= worstZMax - zMax; 
      for (var z = 1; z <= zMax; z++) 
      { 
       iteration++; //count this iteration 
       Thread.Sleep(5); // The process 

       // The progress calculation 
       var progress = (double)iteration/total * pgb.Maximum; 

       bgw.ReportProgress((int)progress); 
      } 
     } 
    } 
} 

आशा इस मदद करता है!

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