Reputation: 27643
I have a BackgroundWorker
that calls a method that calls a method... and somewhere along the line I check for CancellationPending
and want to exit the BackgroundWorker
.
Is there a way to do that directly from that deeply nested method or does it have to return to its caller, which in turn will return to its caller...?
Upvotes: 2
Views: 286
Reputation: 4802
You can, but you shouldn't.
Aside from throwing exceptions as mentioned in other answers, the evil whose name no one dares speak is Thread.Abort(). If you call this from a function executing on the BackgroundWorker thread, the whole thread will quit. The evils of Thread.Abort() have been discussed at great length elsewhere on this site.
That being said, the correct thing to do is to structure your code so that when a deeply-nested function decides that the thread should exit, this intention is propogated back up the stack to the main thread method, which can then exit cleanly
Upvotes: 0
Reputation: 8656
There are many ways to it, I prefer this implementation, although it restricts arguments a little bit but you can change that. The main point is that you are passing the reference to the BackgroudWorker
as a parameter:
bkgw = new BackgroundWorker();
bkgw.DoWork += new DoWorkEventHandler(bkgw_DoWork);
bkgw.WorkerSupportsCancellation = true;
void bkgw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker b = (BackgroundWorker)sender;
if (b.CancellationPending)
{
e.Cancel = true;
return;
}
if (!Method1(b))
{
e.Cancel = true;
return;
}
if (b.CancellationPending)
{
e.Cancel = true;
return;
}
}
bool Method1(BackgroundWorker caller)
{
//some code
if (caller.CancellationPending)
return false;
if (!Method2(caller))
return false;
//some code
return true;
}
bool Method2(BackgroundWorker caller)
{
//some code
if (caller.CancellationPending)
return false;
//some code
return true;
}
Upvotes: 0
Reputation: 9660
There is nothing special about the fact that you're using a BackgroundWorker
- think about this in the same terms as you would just dealing with deeply nested method calls.
In other words, no, there's no (non-horrible) way I can think of to do that directly.
The cleanest way I can think of is to simply check for CancellationPending
immediately after you return from each nested method, at every level (and if true
, return).
Throwing a specific exception and catching same specific exception type at the top level would get you out quickly but isn't exactly best practice (which is, don't use exceptions anything non-exceptional, like normal flow control).
Upvotes: 4
Reputation: 273179
a BackgroundWorker that calls a method that calls a method ...
Is there a way to do that [cancel] directly from that deeply nested method
You could throw an exception. But that is borderline with the general advice to only use exceptions for errors.
Upvotes: 3