What is the best way to exit gracefully when the user closes the form while a background worker is working.
I have tried putting cancelasync in formclosing event but i am getting exceptions on Application.DoEvents()
this is inside the calling function
while (bgwDownload.IsBusy && !bgwDownload.CancellationPending)
{
Application.DoEvents();
}
this is inside my do work
for (int i = 0; i < chunks; i++)
{
bytes_read = from_web.Read(buffer, 0, buffer.Length);
to_file.Write(buffer, 0, bytes_read);
sender.ReportProgress(i * 100 / chunks);
if (sender.CancellationPending)
{
from_web.Close();
to_file.Close();
response.Close();
e.Cancel = true;
Thread.Sleep(100);
return;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (bgwDownload.IsBusy)
{
bgwDownload.CancelAsync();
//Allow a little time to get things done
Thread.Sleep(100);
}
}
}
thanks

Canceling BackgroundWorker when app exits
edukulla
You also shouldn't need to sleep to wait for things to finish - that's potentially a problem.
Here's some sample code that doesn't need to use DoEvents() and doesn't need to use a Sleep to wait for things to finish. (It uses a sleep in the DoWork(), but that is merely to simulate a slow process.)
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
this.backgroundWorker1.RunWorkerAsync();
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (;;) // Simulate work.
{
System.Threading.Thread.Sleep(10000);
if (this.backgroundWorker1.CancellationPending)
break;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (this.closePending)
{
this.closePending = false;
this.Close();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (!this.closePending && this.backgroundWorker1.IsBusy)
{
this.backgroundWorker1.CancelAsync();
this.Cursor = Cursors.WaitCursor;
e.Cancel = true;
this.closePending = true;
}
}
private bool closePending;
}