Reputation: 645
Almost all the example of backgroundworker consists of for loop. But my requirement do not need any loop. I have following code running i backgroundworker. How do i cancel the worker process without using the for loop
void form_DoWork(LoadingProgress sender, DoWorkEventArgs e)
{
//for (int i = 0; i < 100; i++)
//{
// System.Threading.Thread.Sleep(50);
// sender.SetProgress(i, "Step " + i.ToString() + " / 100...");
// if (sender.CancellationPending)
// {
// e.Cancel = true;
// return;
// }
//}
// heavy database process
SomeClass.BulkInsert(ExportLine);
}
private void ButtonCancelClick(object sender, EventArgs e)
{
//notify the background worker we want to cancel
worker.CancelAsync();
//disable the cancel button and change the status text
buttonCancel.Enabled = false;
labelStatus.Text = CancellingText;
}
Upvotes: 1
Views: 757
Reputation: 1996
I wouldn't use BackgroundWorker if that's what you need to do. Since your class doesn't provide any way to provide progress updates, the only thing it's giving you is marshalling the RunWorkerCompleted
method.
Create a Thread class, keep a reference to it and abort if you need to. Just make sure that when your background work is finished, you call Invoke if you update any controls with the results.
EDIT:
Here's a primitive example of how it could work. (note: this may not compile, i didn't write it in the IDE).
Thread _dbThread;
void DoLongRunningQueryAsync()
{
bool dbWorkFinished = false;
_dbThread = new Thread(() =>
{
// heavy database process
SomeClass.BulkInsert(ExportLine);
dbWorkFinished = true;
});
Thread monitorThread = new Thread(() =>
{
Thread.Sleep(5000);
if (!dbWorkFinished)
{
//Db work took too long. Abort
_dbThread.Abort();
this.Invoke(() => MessageBox.Show("Db work took too long. Query aborted"); );
}
});
_dbThread.Start();
monitorThread.Start();
}
private void ButtonCancelClick(object sender, EventArgs e)
{
_dbThread.Abort()
}
Upvotes: 2