From: Tom P. on
I have an application that uses a BackgroundWorker to get a list of
files. The user can navigate away from this to a different directory
so there needs to be a way to interrupt the BackgroundWorker and
restart with a different base path.

The problem I have is if I check IsBusy and call CancelAsync() and
wait for the backgroundWorker the wait loop is too tight for the
BackgroundWorker to communicate with the UI thread (unless I use
DoEvents). If I don't check IsBusy, just call CancelAsync and restart
the process the UI thread gets the cancel flag set after the second
DoWork call and the BackgroundWorker is never able to start the second
process.

Any ideas on how to reuse a BackgroundWorker?

Thanks,
Tom P.
From: Patrice on
Hello,

> The problem I have is if I check IsBusy and call CancelAsync() and
> wait for the backgroundWorker the wait loop is too tight for the
> BackgroundWorker to communicate with the UI thread (unless I use
> DoEvents).

Not sure what is the purpose of this loop. AFAIK you still get a completed
event when cancelling so you could be able to just restart the background
worker from this event if it make sense...

--
Patrice




From: Tom P. on
On Apr 16, 11:30 am, "Patrice" <http://www.chez.com/scribe/> wrote:
> Hello,
>
> > The problem I have is if I check IsBusy and call CancelAsync() and
> > wait for the backgroundWorker the wait loop is too tight for the
> > BackgroundWorker to communicate with the UI thread (unless I use
> > DoEvents).
>
> Not sure what is the purpose of this loop. AFAIK you still get a completed
> event when cancelling so you could be able to just restart the background
> worker from this event if it make sense...
>
> --
> Patrice

The BackgroundWorker has an IsBusy property that should be checked to
determine if the thread is already busy processing. So, to wait for
the BackgroundWorker to finish you would wait in a loop, like so...

_worker.CancelAsync()
while(_worker.IsBusy)
{ }

//Next line of code.


But, since the RunWorkerCompleted event fires on the UI thread, if I
keep the UI thread busy waiting for a cancel then the UI thread won't
have the opportunity to set the canceled flag. If I don't wait there
is no way for the UI thread to determine which call to RunWorkerAsync
is being canceled, so they both are.

Tom P.
From: Family Tree Mike on
On 4/16/2010 2:09 PM, Tom P. wrote:
> On Apr 16, 11:30 am, "Patrice"<http://www.chez.com/scribe/> wrote:
>> Hello,
>>
>>> The problem I have is if I check IsBusy and call CancelAsync() and
>>> wait for the backgroundWorker the wait loop is too tight for the
>>> BackgroundWorker to communicate with the UI thread (unless I use
>>> DoEvents).
>>
>> Not sure what is the purpose of this loop. AFAIK you still get a completed
>> event when cancelling so you could be able to just restart the background
>> worker from this event if it make sense...
>>
>> --
>> Patrice
>
> The BackgroundWorker has an IsBusy property that should be checked to
> determine if the thread is already busy processing. So, to wait for
> the BackgroundWorker to finish you would wait in a loop, like so...
>
> _worker.CancelAsync()
> while(_worker.IsBusy)
> { }
>
> //Next line of code.
>
>
> But, since the RunWorkerCompleted event fires on the UI thread, if I
> keep the UI thread busy waiting for a cancel then the UI thread won't
> have the opportunity to set the canceled flag. If I don't wait there
> is no way for the UI thread to determine which call to RunWorkerAsync
> is being canceled, so they both are.
>
> Tom P.


It seems as if you should be placing everything you have after the call
to CancelAsync, into the handler for the RunWorkerCompleted event.

--
Mike
From: Patrice on
> But, since the RunWorkerCompleted event fires on the UI thread, if I
> keep the UI thread busy waiting for a cancel then the UI thread won't
> have the opportunity to set the canceled flag.

So what if you just let the RunWorkerCompleted event to happen rather than
keeping the UI thread busy with this loop ? You should have a property that
allows to check if this is a normal termination or if it happened through
cancellation so I'm not sure you would need your own flag for this...

> If I don't wait there
> is no way for the UI thread to determine which call to RunWorkerAsync
> is being canceled, so they both are.

Not sure what you mean. AFAIK you can't calll RunWorkerAsync again if the
BackgroundWorker is still busy so you can only cancel the current work

So to try to be more accurate despite my English, my approach would be :
- when you need to cancel just do that and set a flag that tells you need a
next run
- when the RunWorkerCompleted event happens, you know you need a next run
and you could well be able to call RunWorkerAsync again from the
RunWorkerCompleted event (this is IMO the risky part of my architecture,
depends if the BackgroundWorker is considered still busy in this event but
hopefully...).

If the later point is ok I believe this approach would be quite easy to
code.

As this point it's likely better to work on the minimal amount of code
needed to show this point. Let me know if you have something to show. I'll
try on my side but right now I don't have C# handy as I'm already
uninstalling old stuff to clean up the place for 2010 ;-)
--
Patrice