Cancel BackgroundWorker

J

jp2msft

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!
 
J

jp2msft

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!
 
J

jp2msft

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.
 
J

jp2msft

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<string> Employees = (List<string>)e.Argument;
List<string> Errors = new List<string>();
List<string> Results = 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<string> Results = (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.
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top