2013-08-22 12 views
1

我愿意报告密集任务(I/O)的进度。我一直在阅读所有的方法,界面,backGroundWorker,Progress,但没有人包含任何类型的额外信息,例如任务的当前阶段。所以我写了这个方法,如果你能给我任何反馈,建议或评论,我会很高兴。我正在一个winforms 4.0项目中工作。用阶段优先的方法报告线程进度

这是任务

class _ThreadTest 
     { 
     public static void ReporteProgreso(out int p, out string stage) 
     { 
      p = 0; 
      stage = ""; 
      for (int i = 0; i < 10; i++) 
      { 

       System.Threading.Thread.Sleep(500); 
       p++; 

       switch (p) 
       { 
        case 0: stage = "init"; break; 
        case 1: stage = "Loading Data"; break; 
        case 2: stage = "Parsing Data"; break; 
        case 3: stage = "Checking"; break; 
        case 4: stage = "Inserting n Records"; break; 
        case 5: stage = "10%"; break; 
        case 6: stage = "50%"; break; 
        case 7: stage = "70%"; break; 
        case 8: stage = "100%"; break; 
        case 9: stage = "finish"; break;       

        default: 
         break; 
       } 
      } 

     } 
    } 

,这里是我怎么称呼它

static void Main() 
     { 

     //Reportar progreson con OUT 
     int p = 0; 
     string stage = ""; 
     _ThreadTest t = new _ThreadTest(); 
     Thread oThread = new Thread(() => _ThreadTest.ReporteProgreso(out p,out stage)) ; 
     oThread.Start(); 

     int tmp = 0; 
     while (oThread.IsAlive) 
     { 

      if (tmp != p) 
      { 
       Console.WriteLine(stage); 
       tmp = p; 
      } 
     } 

     Console.ReadKey(); 

    } 
} 

有没有什么有趣的测试,更好的方式来实现这一目标?由于这种方法适用于我,所以在某些类型的环境中使用它可能并不安全。

回答

2

BackgroundWorker.ReportProgress完全正是你想要做的。第二个参数是包含您的自定义进度报告的对象。

这第二个参数是在ProgressChangedEventArgsUserState的属性一样传递给ProgressChanged事件处理程序。

BackgroundWorker MSDN主题有一个很好的例子。该例中唯一缺少的是如何使用UserState。这是一个对象,所以你需要施放它。所以,如果您的通话ReportProgress是:

ReportProgress(1, "Loading data"); 

然后在你的ProgressChanged事件处理程序,你将它转换回字符串:

// This event handler updates the progress. 
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    resultLabel.Text = (string)e.UserState 
} 
+0

这将工作正常,但也许我有点意识到处理事件和代表。我打算取得进展的方法是在我的应用的另一层。据我所知,我需要创建事件并从方法本身开始,然后用订阅来处理它。 我写一些代码来测试,如果我可以实现backgroundworker到我的方法,然后尝试订阅它触发的事件。如果我可以得到一些工作代码,我会更新病毒。感谢您的帮助@Jim –

1

我发现与我的工作需要一种方法

在我的昂贵的任务,我处理他的舞台像这样的事情

public static class ExpensiveTasks 
{ 
    public static IEnumerable<KeyValuePair<String, int>> ExpensiveTask1(int sleepTime) 
    { 
     for (int i = 1; i <= 100; i++) 
     { 
      System.Threading.Thread.Sleep(sleepTime); 
      yield return new KeyValuePair<String, int>("Reporting Progress", i); 
     } 
    } 
} 

再从谁调用它的方法,使用BackgroundWorker的DoWork的事件是这样的

void bW_DoWork(object sender, DoWorkEventArgs e) 
    {    
     //var args = e.Argument;    
     BackgroundWorker _bw = sender as BackgroundWorker; 

     foreach (var report in ExpensiveTasks.ExpensiveTask1(100)) 
     { 
      if (_bw.CancellationPending == true) 
      { 
       e.Cancel = true; 
       return; 
      } 
      _bw.ReportProgress(report.Value,report.Key); 
     } 
     e.Result = "The End";   
    } 

用这种方法我可以保持,当然我的层状结构 我可以以某种方式发送BWWorker到昂贵的参考任务,但也许它会在另一层或模块下.T所以至少用这种方式来做这件事,一直在为我工作。

:)