I’ve a backgroundworker which take care of a timer in my application. This is the code:
protected override void OnLoad(EventArgs e)
{
// Inizializzo il backgroundworker
bgwTimer.WorkerReportsProgress = true;
bgwTimer.WorkerSupportsCancellation = true;
bgwTimer.DoWork += (bgwTimer_DoWork);
bgwTimer.RunWorkerCompleted +=(bgwTimer_RunWorkerCompleted);
bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged);
}
void bgwTimer_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
throw new NotImplementedException();
}
void bgwTimer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
throw new NotImplementedException();
}
Basically the event “ProgressChanged” is never fired and so I cannot update the status of a progressbar.
The event DoWork is linked to this method:
void bgwTimer_DoWork(object sender, DoWorkEventArgs e)
{
int i = 0;
if (bgwTimer.CancellationPending)
{
e.Cancel = true;
}
else
{
while (bgwTimer.IsBusy)
{
Thread.Sleep(1000);
bgwTimer.ReportProgress(i);
refreshTimer();
}
}
}
By my side the code looks good and it runs fine. As you can see the ReportProgress method is called but the event is not fired. Any hints?
UPDATE:
Whops! I found that the event “bgwTimer_ProgressChanged” is fired only if I run the RunWorkerAsync right after the declaration of event. Basically:
bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged);
bgwTimer.RunWorkerAsync(); //this works!
Since I run the worker when the user press a button, the event is not triggered.
Here’s the code of click event button:
private void btnNext_Click(object sender, EventArgs e)
{
this.TopMost = true;
btnNext.Enabled = false;
progressBar1.Step = 0;
if (_bgwTimer.IsBusy)
_bgwTimer.CancelAsync();
else
_bgwTimer.RunWorkerAsync();
}
Put a breakpoint, or a
Debug.PrintorSystem.Windows.Forms.Messageboxjust beforebgwTimer.ReportProgress(i), to verify that you’re actually entering thewhileloop.Note that the
BackgroundWorkeris not actually a timer; it’s a wrapper for a thread that provides a threadsafe invoking layer for your user interface.Your
if (bgwTimer.CancellationPending) { }should be inside thewhileloop, not outside it. It will only get checked once in your current code.Note that, if you’re inside the
DoWorkevent handler, then by definition you’re running an asynchronous process, soIsBusyshould always be true (according to the MSDN documentation), and therefore yourwhileis an infinite loop. But check it with your debugger.