Rob
Rob

Reputation: 312

Close form after stopping background worker not working

I have been trying many different thing and can't get this code to work. My code to stop backgroundworker then close window.

protected override void OnFormClosing(FormClosingEventArgs e)
    {
        if (bw.IsBusy)
        {
            bw.CancelAsync();
            e.Cancel = true;
            MessageBox.Show("close"); //Does show
            return;
        }
        base.OnFormClosing(e);
    }

During bw worker

if (worker.CancellationPending)
        {
            MessageBox.Show("Cancel"); // Does not show
            //Cancel
            e.Cancel = true;
        }

On completed background worker

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Completed"); //Does not work

        //Check if restart
        if (bw_restart)
        { 
            bw_restart = false;
            bw.RunWorkerAsync();

        }
        //If it was cancelled
        if (e.Cancelled)
        {
            this.Close();
        }
        //If error show error message
        else if (e.Error != null)
        {
            MessageBox.Show(e.Error.ToString()); // Does not show
        }
        else //No errors or cancelled
        {
            MessageBox.Show(e.ToString()); //Does not shoiw
        }

    }

Cancel button

private void cancel_Click(object sender, EventArgs e)
    {
        bw.CancelAsync(); //Does not work :s
    }

It does not close the window, the X when pressed does not do anything, I got it to close the form but not with stopping the background worker, driving me a bit mad. Link to code i got for this problem that not working: How to stop BackgroundWorker on Form's Closing event?

Upvotes: 0

Views: 912

Answers (3)

nirmus
nirmus

Reputation: 5093

CancelAsync doesn't actually abort your thread or anything like that. It sends a message to the worker thread that work should be cancelled via BackgroundWorker.CancellationPending. Your DoWork delegate that is being ran in the background must periodically check this property and handle the cancellation itself.

Look at this:

    private BackgroundWorker background;

    private void Form1_Load(object sender, EventArgs e)
    {
        background = new BackgroundWorker();
        background.WorkerSupportsCancellation = true;
        background.DoWork += BackgroundOnDoWork;
        background.RunWorkerCompleted += BackgroundOnRunWorkerCompleted;

        background.RunWorkerAsync();
    }

    private void BackgroundOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
    {
        MessageBox.Show("stop");
    }

    private void BackgroundOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
    {
        // your doWork loop should check if someone don't call background.CancelAsync();
        while (!background.CancellationPending) 
        {
            // do something
        }
    }

    private void ButtonClick(object sender, EventArgs e)
    {
        background.CancelAsync();
    }

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 941327

   if (e.Cancelled)

That's fundamentally wrong. You can never be 100% sure that it will be set. Canceling a BGW is always a race condition, the BGW might have been busy exiting when you called its CancelAsync() method so never saw the CancellationPending set to true so never assigned e.Cancel = true in the DoWork event handler.

All you know for a fact is that mClosePending is reliable, since it was set to true on the UI thread. So always call Close() it it is set to true, regardless of the e.Cancelled state.

And yes, checking e.Error doesn't hurt either. But still check mClosePending.

Upvotes: 2

Sayse
Sayse

Reputation: 43300

As stated in my comment, your BackgroundWorker has ended due to an error, try adding the following at the top of your run worker completed. Once this error has been resolved your question will be more answerable.

if(e.Error != null)
     MessageBox.Show(e.Error.toString());//Put a breakpoint here also

Upvotes: 1

Related Questions