Reputation: 39
Hello I am trying to populate a progress bar but the ReportProgress call its not been executed for some reason.
Here is my code
//create status_Worker
status_Worker = new BackgroundWorker();
status_Worker.DoWork += new DoWorkEventHandler(Status_DoWork);
status_Worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
status_Worker.WorkerReportsProgress = true;
status_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
private void Status_DoWork(object sender, DoWorkEventArgs e)
{
//make call to Logger class getStatus method
_logger.getStatus(sender);
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressbar1.Value = e.ProgressPercentage;
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}
else
{
Start_button.IsEnabled = true;
}
}
private void Start_button_Click(object sender, RoutedEventArgs e)
{
//initiate status_Worker when button is clicked
status_Worker.RunWorkerAsync();
Start_button.IsEnabled = false;
}
Now inside the Logger class I have the getStatus() method. i make a call to a local server to get status of the files been processed and all that works and I see the values been updated automatically on my MainWindow.Status.
public async Task getStatus(object sender)
{
BackgroundWorker statusWorker = (BackgroundWorker)sender;
//Making a call to ReportProgress here works and it shows the progress bar
//statusWorker.ReportProgress(99);
//REQUEST STATUS from a server
//Status format
//CurrentParser, NumberOfFilesToParse,CountOfCompletedFiles,Status, NumberOfProcessRunning
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
Thread.Sleep(1000);
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
//a call to ReportProgress here stalls the program at this point
//statusWorker.ReportProgress(percent);
}
}
MainWindow.main.Status = "Completed!";
}
A call to ReportProgress at the start of the getStatus method works but a call to ReportProgress during or after my while loop results in process stalling at that point. Even when using static numbers ReportProgress(99) it only executes at the beginning
Upvotes: 0
Views: 291
Reputation: 456437
Your Status_DoWork
method is doing fire-and-forget. It's calling an async Task
method and then ignoring the Task
it returns.
One of the problems you've run into is that BackgroundWorker
simply doesn't work with async
. What's actually happening is that as soon as the first await
is reached in getStatus
, it returns an incomplete Task
to Status_DoWork
, which then exits. This causes the BackgroundWorker
to finish, so raising progress events no longer makes sense for that BackgroundWorker
.
The modern replacement for BackgroundWorker
is Task.Run
, which includes support for progress reporting. Ideally, you would only use Task.Run
for CPU-bound methods, not the I/O-bound methods:
private void Start_button_Click(object sender, RoutedEventArgs e)
{
Start_button.IsEnabled = false;
var progress = new Progress<int>(update => progressbar1.Value = update);
try
{
await _logger.getStatus(progress);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
Start_button.IsEnabled = true;
}
}
public async Task getStatus(IProgress<int> progress)
{
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
await Task.Run(() => Thread.Sleep(1000)); // process file in Task.Run
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
progress.Report(percent);
}
}
MainWindow.main.Status = "Completed!";
}
Upvotes: 2