-2

The whole program freeze and gray like enabled false i can't click on it do nothing only close it from the visual studio Stop Debugging.

It started once after i added: protected override void OnFormClosing

bool mCompleted = false;
bool mClosePending = false;
protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (!mCompleted)
    {
        backgroundWorker1.CancelAsync();
        this.Enabled = false;
        e.Cancel = true;
        mClosePending = true;
        return;
    }
    base.OnFormClosing(e);
}

I added this override since i wanted to make sure the backgroundworker i'm using was stop before closing the form1 when i click the right top x. So it is working while the backgroundworker is running but when the backgroundworker is not running i just run the program and click the x then the whole program is like enabled false and all i can do is shut it down by stop debugging.

In backgroundworker completed event i did:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled == true)
    {

    }
    if (e.Error != null)
    {

    }
    else
    {
        mCompleted = true;
        if (mClosePending) this.Close();
    }
}

But the problem happen when the backgroundworker is not running and i just click the x.

  • 1
    Well, you disable the form and cancel the closing op. What else do you expect to happen here? – Steve Jul 10 '16 at 07:18
  • 1
    I think the problem is : this.Enabled = false; – klaymen Jul 10 '16 at 07:21
  • 3
    I changed [the sample code](http://stackoverflow.com/a/1732361/17034) to be a bit more resilient to mistakes like this. Google "attribution required" and take the first hit. – Hans Passant Jul 10 '16 at 08:14

3 Answers3

1

By setting Cancel to true you are effectively aborting the form closing and leaving it disabled:

this.Enabled = false;
e.Cancel = true;

You should add a check to make sure the BackgroundWorker is running so it will eventually close the form.

You might also want to add a timeout in case the worker get stuck in some cases depending on your worker's job.

Ideally you would use a wait event to wait for the worker to finish and then close the form rather than relying on the worker to close it so you can keep the closing logic in one place.

Have a look at this answer: How to wait for BackgroundWorker to finish and then exit console application

Community
  • 1
  • 1
Stefano d'Antonio
  • 5,874
  • 3
  • 32
  • 45
1

If your flag mCompleted is false in the OnClosing override you enter the first if condition without checking if your background worker is running or not. This disables the main form (this.Enabled = false;) and cancels the closing (e.Cancel = true;) even if the background worker is not running. At this point there is no code that closes the form because obviously the WorkerCompleted event is not raised on a not running BackgroundWorker.

You need to check the IsBusy property.

if (!mCompleted && backgroundWorker1.IsBusy)
{
    backgroundWorker1.CancelAsync();
    this.Enabled = false;
    e.Cancel = true;
    mClosePending = true;
    return;
 }
 base.OnFormClosing(e);
Steve
  • 213,761
  • 22
  • 232
  • 286
0

I think that use with flag is most simple. The flag will update in:

ProgressChanged(object sender, ProgressChangedEventArgs e)

or in the Timer option.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
user1012506
  • 2,048
  • 1
  • 26
  • 45