2016-12-14 3 views
5

나는 BackgroundWorker와 하나의 ProgressBar를 가지고있다. 작업 할 때 BackgroundWorker는 for 루프를 실행하고 ProgressBar로 진행 상황을보고합니다.중첩 루프 (진행률 막대)의 여러 변수를 기반으로 진행 상황을보고하려면 어떻게해야합니까?

현재보고되는 진행 상황은 정상적으로 작동하지만 원활하게 실행되지 않는 최단 루프 (xProgress)의 진행 상황입니다. 목표는 ProgressBar가 내부 루프의 진행률을 고려하여 ProgressBar가보다 원활하고 정확하게 업데이트되도록하는 것입니다.

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 % 일 때 'x'를 1 씩 늘리므로 '100 % y'가 '1 % x'이고 z 및 y가 동일하다고 말할 수 있습니다 . 그래서'var prog = xProg + yProg * 0.01d * xMax + zProg * 0.01d * yMax * 0.01d * xMax' (또는 * 그와 비슷한 것). 루프를 0에서 최대 1 대신 'max-1'로 설정해야 루프를 올바르게 계산할 수 있지만 확실하지는 않습니다. 확인해야합니다. – 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에 의해 진행 상황을 곱 것입니다. 그런 식으로 스레드 된 메서드는 UI 요소를 전혀 건드리지 않습니다.

1

업데이트 답 : 내부 루프는 당신이 진행하는 방법을 여러 단계를 결정할 수 반복 알 수없는 번호가

입니다. 예를 들어 다음 10

을 위해 당신이 뭔가를 할 수 있습니다 :

progressbarMaximum = xMax * yMax * 10 

바로 Z-루프 전에 당신은 당신의 Z-루프 체크 10. 와 ZMAX을 나누어 zModulo를 얻을 수

zMax % zModulo == 0 
경우

다음 진행률 표시 줄을 증가시킵니다.

올드 대답 : 당신이 XMAX, yMax 인 및 ZMAX을 곱하면

당신은 가장 안쪽의 루프의 반복의 총 수를 얻을.

최대 값으로 진행 막대를 설정하십시오.

내부 루프 증가 진행률 막대를 반복 할 때마다.

+0

불행히도 코드에 표시된 것처럼 각 z에 대해 zMax가 변경됩니다. 따라서 반복되는 전체 반복 횟수를 알지 못합니다. – DomTheDeveloper

0

일 수 없습니다. 이 방법으로 생각해보십시오. 첫 번째 무작위 라운드가 모두 50 개이고 이미 2 개의 외부 루프의 절반을 완료 한 경우 - 나머지 50 개가 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); 
      } 
     } 
    } 
} 

희망!