472,972 Members | 2,048 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,972 software developers and data experts.

Cancel BackgroundWorker

How do you cancel a BackgroundWorker?

For this BackgroundWorker:

bgWorker.WorkerReportsProgress = true;
bgWorker.WorkerSupportsCancellation = true;

I have tried this, but it never exits the do...while loop:

if (bgWorker.IsBusy == true) {
bgWorker.CancelAsync();
}
do {
Thread.Sleep(0);
} while (bgWorker.IsBusy == true);

I tried removing the do...while loop, but then I get errors because the
thread is still being used!
Sep 11 '08 #1
7 4742
On Thu, 11 Sep 2008 11:24:00 -0700, jp2msft
<jp*****@discussions.microsoft.comwrote:
How do you cancel a BackgroundWorker?
See the MSDN documentation for the class. It includes an example of a
cancelable BackgroundWorker.

The short story: your DoWork handler needs to take into account the
possibility of cancellation, checking for that condition at opportune
moments during processing and terminating early when canceled.

From the docs for BackgroundWorker.CancelAsync():

The worker code should periodically check the
CancellationPending property to see if it has
been set to true.

Pete
Sep 11 '08 #2
I copied their example, and I even have my thread checking to see if it has
been cancelled within its loops:

if (worker.CancellationPending == true) {
e.Cancel = true;
return;
}

This part of the code is triggered, but when this happens, the code does not
enter the bgWorker_ProgressChanged or bgWorker_RunWorkerCompleted event
handlers.

Because of this, my do...while loop never exits.

How is this fixed?

BTW: Thanks for your help, too!

"Peter Duniho" wrote:
See the MSDN documentation for the class. It includes an example of a
cancelable BackgroundWorker.

The short story: your DoWork handler needs to take into account the
possibility of cancellation, checking for that condition at opportune
moments during processing and terminating early when canceled.

From the docs for BackgroundWorker.CancelAsync():

The worker code should periodically check the
CancellationPending property to see if it has
been set to true.

Pete
Sep 11 '08 #3
On Thu, 11 Sep 2008 13:17:01 -0700, jp2msft
<jp*****@discussions.microsoft.comwrote:
I copied their example, and I even have my thread checking to see if it
has
been cancelled within its loops:

if (worker.CancellationPending == true) {
e.Cancel = true;
return;
}

This part of the code is triggered, but when this happens, the code does
not
enter the bgWorker_ProgressChanged or bgWorker_RunWorkerCompleted event
handlers.

Because of this, my do...while loop never exits. [...]
Unless you post a concise-but-complete code sample that demonsrates
exactly what you're doing, it's not possible to say what you're doing
wrong. The RunWorkerCompleted event definitely should be raised, but
there's nothing in the code you post that proves that you're handling it,
never mind that it would affect the loop you posted.

The most likely explanation is that the loop you posted is executing on
the main GUI thread, and of course doing so would cause all sorts of
issues, including this one. But without all the code, it's impossible to
say for sure what's going on.

That said, I'll point out that just from the little code you've posted,
it's clear that your basic strategy is simply wrong. There is no sense in
handing off work to a different thread only to have the current thread sit
and wait for it to be done. There also is _especially_ no sense in
writing a "busy wait" as you've done here, where the only thing the loop
does is repeatedly check for a specific condition. Even in situations
where it makes sense for a thread to wait for something to happen (and
this doesn't appear to be such a situation), there are correct ways to
wait, such as using a WaitHandle sub-class, that don't consume CPU
resources uselessly as your code does.

If you can provide a concise-but-complete code sample, I'm sure I or
someone else can provide more useful advice. Until then, I remain
unoptimistic. :)

Pete
Sep 11 '08 #4
I wished I could provide an attachment, but I can't.

I added one ugly Application.DoEvents() to the wait loop, and my thread went
into the RunWorkerCompleted section.

I could email you the file, if you are interested. You can send your email
address to me at jpool at aaon dot com.
Sep 11 '08 #5
On Thu, 11 Sep 2008 14:17:03 -0700, jp2msft
<jp*****@discussions.microsoft.comwrote:
I wished I could provide an attachment, but I can't.
Sure you can. If you want the best answer, you must.

It doesn't have to be the full code you're working with. In fact, it
typically shouldn't be. But it does have to be complete, and it does have
to reproduce the problem.

Every question ever posted to this newsgroup has such as
"concise-but-complete" code sample that goes along with the question.
Often the person posting the question fails to include the sample, but one
always exists.
I added one ugly Application.DoEvents() to the wait loop, and my thread
went
into the RunWorkerCompleted section.
Don't do that. Calling DoEvents() is simply bad generally (the biggest
issue is that it introduces re-entrancy to code that has almost certainly
not been designed with re-entrancy in mind), and in this case it only
emphasizes how defective your current design is (you should never be
blocking the GUI thread, and I'll reiterate that having one thread just
sit and wait for another thread is always the wrong thing to do).
I could email you the file, if you are interested. You can send your
email
address to me at jpool at aaon dot com.
Any code sample I'd be willing to read through would be appropriate to be
posted here.

That said, based on your reply, it sounds like you've confirmed my guess
as to what's wrong. The correct resolution is to fix your design so that
the main GUI thread isn't waiting on the worker thread at all. Put all of
the logic that occurs after the wait into a method that can be called by
the RunWorkerCompleted event handler, or into that handler's method
itself. The main GUI thread should simply start the worker and then
return.

Pete
Sep 11 '08 #6
Ok, here is a small test section that I have put together to illustrate my
problem:

We have an SQL query that takes 60-120 seconds to run for each employee (the
SqlCommand's CommandTimeout is set to 120 seconds and this seems to give the
queries enough time).

public static string m_fmtSql = "SELECT LOTS OF STUFF WHERE EMPLOYEE='{0}'";
public static SqlConnection m_conn; // set elsewhere

void worker_DoWork(object sender, DoWorkEventArgs e) {
List<stringEmployees = (List<string>)e.Argument;
List<stringErrors = new List<string>();
List<stringResults = new List<string>();
BackgroundWorker worker = sender as BackgroundWorker;
int Count = 0;
foreach (string person in Employees) {
if (worker.CancellationPending == true) {
e.Cancel = true;
return;
}
Count++;
worker.ReportProgress(100 * Count / Employees.Count);
DataTable dt = new DataTable();
string sql = string.Format(m_fmtSql, person);
using (SqlDataAdapter da = new SqlDataAdapter(sql, m_conn)) {
try {
da.Fill(dt); // this step takes 60-120 seconds to run
} catch (SqlException err) {
Errors.Add(err.Message);
}
}
if (0 < dt.Rows.Count) {
string fmt = "{0};{1};{2};{3};{4};{5};{6}";
string var1, var2, var3, var4, var5;
int var6, var7;
// work with data, manipulate some figures, then add it to the results
string result
= string.Format(fmt, var1, var2, var3, var4, var5, var6, var7);
Results.Add(result);
}
}
e.Result = Results;
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error != null) {
// display error
} else if (e.Cancelled == true) {
// display that status
} else if (e.Result is List<string>) {
List<stringResults = (List<string>)e.Result;
DataGridView1.Rows.Clear();
foreach (string line in Results) {
string[] data = line.Split(new char[] { ';' });
DataGridView1.Rows.Add(data);
}
}
}

void BtnCancel_Click(object sender, EventArgs e) {
if ((WorkerThread.IsBusy == true) &&
(WorkerThread.SupportsCancellation == true)) {
WorkerThread.CancelAsync();
// Here is the point of concern:
// since the SQL call could take up to 2 full minutes to complete,
// our Users are liable to try running the report again while
// the thread is still active.
// So, the solution is to disable the "Run Report" button until
// this thread has finished:
BtnRunReport.Enabled = false;
do {
Thread.Sleep(0);
} while (WorkerThread.IsBusy == true);
BtnRunReport.Enabled = true;
// The problem is:
// This code is so busy in the loop, that the
// "RunWorkerCompleted" code does not have a chance to run.
// If I write in the ugly "Application.DoEvents();" within the
do...while loop,
// the application will stop itself, but that is a bad fix.
}
}
Sep 12 '08 #7
On Fri, 12 Sep 2008 09:14:07 -0700, jp2msft
<jp*****@discussions.microsoft.comwrote:
Ok, here is a small test section that I have put together to illustrate
my
problem:
Please see http://www.yoda.arachsys.com/csharp/complete.html

Based on what you've written so far in this thread, I believe my previous
comments should be sufficient in helping you fix your code. But if you
feel there's a need for further elaboration, you need to post a true
concise-but-complete code sample. What you just posted is neither.
Sep 12 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Sagaert Johan | last post by:
The backgroundworker contains a blocking call to UDPClient.Receive How do i unlock this thread so the backgroundworker can be cancelled ? Johan
2
by: Steve | last post by:
After running into a design wall with my traditional thread approach, I realized that a BackgroundWorker object would fit my needs pretty good. Never really used them before. In a nutshell, my...
5
by: Rob R. Ainscough | last post by:
I'm using a BackgroundWorker to perform a file download from an ftp site. Per good code design practices where I separate my UI code from my core logic code (in this case my Download file method in...
1
by: David Veeneman | last post by:
Does anyone knmow why an asynchronous worker method would crash if the e.Cancel method is set to true, but not otherwise? I'm working on a demo app with an asynchronous call, using the .NET 2.0...
1
by: Bob | last post by:
Hi, I am having trouble seeing how this bolts together. The UI starts a process which involves a long running database update. All Database activity is handled by a class called DT. DT has a...
9
by: RvGrah | last post by:
I'm completely new to using background threading, though I have downloaded and run through several samples and understood how they worked. My question is: I have an app whose primary form...
4
by: Sin Jeong-hun | last post by:
This is what I've always been wondered. Suppose I've created a class named Agent, and the Agent does some lengthy job. Of course I don't want to block the main window, so the Agent does the job in...
0
by: Smokey Grindel | last post by:
I have a search function that runs in a background worker which can run long.. I want the user to be able to cancel that then run another search... but sometimes it throws an exception saying ...
16
by: parez | last post by:
I start a BackGroundWorker to populate a grid. It is started off in the ui layer The thread follows( cannot think of a better word) the path UI->Layer1->Layer2->Communication Layer and it...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
3
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.