How to handle closing forms when using background workers?

I am observing a strange error in some of my codes, which I suspect are tied to the method of closing the form and background workers.

Here is the code that may be malfunctioning:

var worker = new BackgroundWorker();
    worker.DoWork += (sender, args) => {
        command();
    };
    worker.RunWorkerCompleted += (sender, args) => {
        cleanup();
        if (args.Error != null)
            MessageBox.Show("...", "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    };
    worker.RunWorkerAsync();

This code is executed in the method in the form when the button is clicked. The () command is slow, it may take a few seconds.

The user presses a button that executes the above code. Before you do this, the form is closed.

, cleanup() ObjectDisposedException. "", . (), , RunWorkerCompleted, . . . -, / .

:

BakgroundWorker? , , , "this" "".

:

?

, :

  • , (! this.IsDisposed) cleanup(). , ?
  • cleanup() try {} catch (ObjectDisposedException). , , - - cleanup() , .
  • IsClosing , RunWorker Completed.

, : () GUI "this". F #:

/// Run a delegate on a ISynchronizeInvoke (typically a Windows.Form).
let runOnInvoker (notification_receiver : ISynchronizeInvoke) excHandler (dlg : Delegate) args =
    try
        let args : System.Object[] = args |> Seq.cast |> Array.ofSeq
        notification_receiver.Invoke (dlg, args) |> ignore
    with
        | :? System.InvalidOperationException as op ->
            excHandler(op)
+3
1

, , BackgroundWorker, , () , ( ).

, , - Form.FormClosed, , , . RunWorkerCompleted , , - .

, , , IsDisposed, , 100% , / , , . , .

, , :

// set this to new object() in the constructor
public object CloseMonitor { get; private set; }

public bool HasBeenClosed { get; private set; }

private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
    lock (this.CloseMonitor) {
        this.HasBeenClosed = true;
        // other code
    }
}

:

worker.RunWorkerCompleted += (sender, args) => {
    lock (form.CloseMonitor) {
        if (form.HasBeenClosed) {
            // maybe special code for this case
        }
        else {
            cleanup();
            // and other code
        }
    }
};

Form.FormClosing , , , .

, , , ( , WinForms ), , , , , . , , . , .

+4

Source: https://habr.com/ru/post/1779172/


All Articles