使用backgroundWorker和异步下载更新表单进度条更新

时间:2012-07-09 00:07:59

标签: c# asynchronous progress-bar backgroundworker

这是我进入异步/线程的第一步,所以请提前道歉。我需要一些关于实现以下内容的最佳方法的建议......

我有一个非静态的窗体,包含一个进度条。我还有一个静态方法'HttpSocket'来管理异步http下载。因此,我无法直接从静态方法访问表单进度条。

所以我想过使用backgroundWorker来运行这个工作。但是,因为DoWork也在调用异步方法,所以在完成所有http请求后,backgroundWorker会报告完成,但我想根据收到http响应和解析数据的时间来更新进度条。

我想出的一个可怕的方法如下

private void buttonStartDownload_Click(object sender, EventArgs e)
{
  backgroundWorker1.RunWorkerAsync();
}

并在backgroundWorker1_DoWork中放置一个while循环来比较请求/响应

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    //Trigger Asynchronous method from LoginForm
    DataExtract LoginForm = new DataExtract();
    LoginForm.DELogin();

    //Without While Loop backgroundWorker1 completes on http requests and not responses

    // Attempt to Monitor Progress of async responses using while loop
   // HttpSocket method logs RequestCount & ResponseCount

    while (HttpSocket.UriWebResponseCount < HttpSocket.UriWebRequestCount)
    {

        if (HttpSocket.UriWebResponseCount % updateInterval == 0) 
        {
            int myIntValue = unchecked((int)HttpSocket.UriWebResponseCount / HttpSocket.UriTotal);
            backgroundWorker1.ReportProgress(myIntValue);
        }

    }

}


private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Change the value of the ProgressBar to the BackgroundWorker progress.
    progressBar1.Value = e.ProgressPercentage;

}

然而,我意识到这不是最好的方法,因为While循环会影响性能并减慢异步过程,这通常很快而不会显示进度。 我正在寻找关于正确,最有效的方法来实现这一点的建议,或提供使用C#4.0在有或没有BackgroundWorker的情况下从单独的异步线程更新表单进度条的其他方法吗?

谢谢

0

1 个答案:

答案 0 :(得分:2)

如果没有完全理解请求/响应模型的体系结构,它看起来好像后台工作程序中的while循环基本上正忙着等待。

您可以通过在while循环的顶部插入一个睡眠操作来更频繁地检查进度状态,我还建议在报告进度之前删除检查以查看响应计数是否为整数值。

while (HttpSocket.UriWebResponseCount < HttpSocket.UriWebRequestCount) 
{ 
    Thread.Sleep(250); // sleep for 250 ms before the next check

    int myIntValue = (int)Math.Floor((double)HttpSocket.UriWebResponseCount / HttpSocket.UriTotal); 
    backgroundWorker1.ReportProgress(myIntValue); 
} 

希望以线程安全的方式更新和读取静态属性HttpSocket.UriWebResponseCount和HttpSocket.UriWebRequestCount。