user688334
user688334

Reputation:

Advice on Form progressbar update using backgroundWorker and async downloads

This is my first steps into async/threading so apologies in advance. I need some advice on the best way to implement the following...

I have a windows form which is non-static containing a progress bar. I also have a static method 'HttpSocket' to manage async http downloads. Therefore, I can't access the forms progress bar directly from a static method.

So I thought about using the backgroundWorker to run the job. However, because DoWork is also calling an async method, the backgroundWorker reports complete once all of the http requests are made but I want to update the progress bar based on when the http responses are received and data parsed.

One awful way around this I've come up with is as follows

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

and place a while loop in backgroundWorker1_DoWork to compare requests/responses

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;

}

However, I realise this is not the best way to do this as the While loop impacts performance and slows the async process which is normally fast without showing progress. I'm after suggestions on the proper, most efficient way to accomplish this or offer alternate ways to update a Form progress bar from a separate async thread either with or without BackgroundWorker using C#4.0?

Thank you

O

Upvotes: 2

Views: 908

Answers (1)

Monroe Thomas
Monroe Thomas

Reputation: 5042

Without fully understanding the architecture of your request / response model, it looks as if the while loop in the background worker is essentially busy waiting.

You can check the status of progress much less frequently by inserting a sleep operation at the top of the while loop, and I would also suggest removing the check to see if the response count is an integral value before reporting progress.

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); 
} 

Hopefully the static properties HttpSocket.UriWebResponseCount and HttpSocket.UriWebRequestCount are being updated and read in a thread-safe fashion.

Upvotes: 1

Related Questions