Reputation: 628
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();
}
Upvotes: 1
Views: 4180
Reputation: 941337
You forgot to start the worker. Add this line to your OnLoad() method:
bgwTimer.RunWorkerAsync();
Upvotes: 2
Reputation: 180787
Put a breakpoint, or a Debug.Print
or System.Windows.Forms.Messagebox
just before bgwTimer.ReportProgress(i)
, to verify that you're actually entering the while
loop.
Note that the BackgroundWorker
is 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 the while
loop, not outside it. It will only get checked once in your current code.
Note that, if you're inside the DoWork
event handler, then by definition you're running an asynchronous process, so IsBusy
should always be true (according to the MSDN documentation), and therefore your while
is an infinite loop. But check it with your debugger.
Upvotes: 3
Reputation: 67898
It's not raising the event because the value of i
is always zero, which is helpfully undocumented but I found out the same thing when building a background worker a while back.
Upvotes: 3
Reputation: 9394
In the DoWork-Method replace bgwTimer through ((BackgroundWorker)sender). Maybe this is the problem
Upvotes: 0