BackgroundWorker
Form Closing
C#
Multithreading
Event Handling

How to stop BackgroundWorker on Form's Closing event?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

You do not forcibly “kill” a BackgroundWorker when a WinForms form is closing. The correct pattern is cooperative cancellation: request cancellation, let the worker notice it, and delay the final close until the worker finishes cleanly.

Enable Cancellation First

A BackgroundWorker can only respond to cancellation if WorkerSupportsCancellation is enabled and the DoWork logic checks the cancellation flag.

csharp
backgroundWorker1.WorkerSupportsCancellation = true;

Then the worker code must cooperate.

csharp
1private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
2{
3    var worker = (BackgroundWorker)sender;
4
5    for (int i = 0; i < 100000; i++)
6    {
7        if (worker.CancellationPending)
8        {
9            e.Cancel = true;
10            return;
11        }
12
13        Thread.Sleep(10);
14    }
15}

If the worker never checks CancellationPending, calling CancelAsync() will not stop it.

Cancel During FormClosing

When the user closes the form, request cancellation and keep the form open until the worker actually exits.

csharp
1private bool _closingRequested;
2
3private void Form1_FormClosing(object sender, FormClosingEventArgs e)
4{
5    if (backgroundWorker1.IsBusy)
6    {
7        e.Cancel = true;
8        _closingRequested = true;
9        backgroundWorker1.CancelAsync();
10        this.Enabled = false;
11    }
12}

The important part is e.Cancel = true. That prevents the form from disposing while background work is still active.

Finish the Close in RunWorkerCompleted

Once the worker exits, close the form for real.

csharp
1private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
2{
3    this.Enabled = true;
4
5    if (_closingRequested)
6    {
7        Close();
8    }
9}

This gives the worker a chance to end in a controlled way instead of tearing down UI state under it.

Why Blocking the UI Thread Is a Bad Idea

A common mistake is calling CancelAsync() and then waiting in a loop for IsBusy to become false. That blocks the UI thread and can freeze the form exactly when the user is trying to close it.

Let the event-driven flow handle completion instead. BackgroundWorker was designed around asynchronous completion, not around synchronous waiting from the form thread.

Consider Modern Alternatives

BackgroundWorker still works, but in newer .NET code, Task, CancellationToken, and async or await usually provide a cleaner cancellation model. If you are maintaining older WinForms code, keep BackgroundWorker cancellation cooperative and simple rather than mixing it with ad hoc thread control.

Disable New Work While Shutdown Is Pending

Once closing has started, avoid letting the user queue more work. Disabling buttons or the form itself during cancellation makes shutdown behavior much more predictable and prevents race conditions where the UI starts a second worker just as the first one is being canceled.

That small UX step often removes a surprising amount of shutdown complexity in older WinForms code.

Show the User What Is Happening

If cancellation may take a moment, update the form so the user understands why it did not disappear instantly. A short status label such as "Stopping background work..." is often enough to make the behavior feel intentional rather than broken.

That small feedback loop matters because graceful shutdown is both a threading concern and a user-experience concern.

Common Pitfalls

The biggest mistake is assuming CancelAsync() stops the worker immediately. It only requests cancellation.

Another issue is closing or disposing the form before the worker has actually finished using shared state.

A third problem is blocking the UI thread while waiting for the worker to finish, which makes the application feel hung.

Summary

  • Stop a BackgroundWorker with cooperative cancellation, not forced termination.
  • Enable WorkerSupportsCancellation and check CancellationPending inside DoWork.
  • In FormClosing, call CancelAsync() and cancel the close temporarily.
  • Finish the real close from RunWorkerCompleted after the worker exits.
  • Do not block the UI thread while waiting for background work to stop.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.