CodexBloom - Programming Q&A Platform

WinForms: Handling Multiple BackgroundWorker Instances with Cancellation Tokens

๐Ÿ‘€ Views: 30 ๐Ÿ’ฌ Answers: 1 ๐Ÿ“… Created: 2025-07-24
winforms backgroundworker cancellation ui C#

I'm sure I'm missing something obvious here, but I'm encountering an issue while using multiple instances of `BackgroundWorker` in my WinForms application to perform some long-running tasks. I need to be able to cancel these tasks gracefully when the user decides to stop them. However, I'm running into a scenario where I end up with unresponsive UI elements even after I attempt to cancel the workers. I've set up my `BackgroundWorker` instances, but they don't seem to respect the cancellation requests properly. Hereโ€™s a simplified version of my code: ```csharp private BackgroundWorker worker1; private BackgroundWorker worker2; public MainForm() { InitializeComponent(); worker1 = new BackgroundWorker(); worker1.WorkerSupportsCancellation = true; worker1.DoWork += Worker_DoWork; worker1.RunWorkerCompleted += Worker_RunWorkerCompleted; worker2 = new BackgroundWorker(); worker2.WorkerSupportsCancellation = true; worker2.DoWork += Worker_DoWork; worker2.RunWorkerCompleted += Worker_RunWorkerCompleted; } private void StartWorker1Button_Click(object sender, EventArgs e) { if (!worker1.IsBusy) worker1.RunWorkerAsync(); } private void StartWorker2Button_Click(object sender, EventArgs e) { if (!worker2.IsBusy) worker2.RunWorkerAsync(); } private void CancelWorkersButton_Click(object sender, EventArgs e) { if (worker1.IsBusy) worker1.CancelAsync(); if (worker2.IsBusy) worker2.CancelAsync(); } private void Worker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 0; i < 100; i++) { if (worker.CancellationPending) { e.Cancel = true; return; } // Simulating a long-running task Thread.Sleep(100); } } private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("Operation was cancelled."); } else if (e.Error != null) { MessageBox.Show("Error: " + e.Error.Message); } else { MessageBox.Show("Operation completed successfully."); } } ``` Despite setting `WorkerSupportsCancellation` to true and checking `CancellationPending` inside the `DoWork` method, it seems that the cancellation request is sometimes ignored, especially when tasks are running consecutively. Iโ€™ve also tried adding a small delay before checking for cancellation, but that didnโ€™t seem to help. The UI freezes momentarily during the cancellation process, and sometimes I get the following error: `InvalidOperationException: Cross-thread operation not valid: Control '...' accessed from a thread other than the thread it was created on.` Is there a best practice for handling cancellation with multiple `BackgroundWorker` instances in WinForms? What could be causing the UI to become unresponsive during the cancellation process? Am I missing something obvious? Has anyone else encountered this?