Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How close BackgroundWorker thread when application is deactivated?

I create thread with BackgroundWorker, and in the loop I check every time if CancellationPending is true or not, like this:

   public MainPage()
    {
        InitializeComponent();

        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    }

    private void ButtonStart_Click(object sender, RoutedEventArgs e)
    {
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }

    private void ButtonCancel_Click(object sender, RoutedEventArgs e)
    {
        if (bw.WorkerSupportsCancellation)
        {
            bw.CancelAsync();
        }
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        for (int i = 1; i <= 100; i++)
        {
            Debug.WriteLine("The tread is working");
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                bw.CancelAsync();
                break;
            }
            else
            {

                System.Threading.Thread.Sleep(500);
                worker.ReportProgress(i);
            }
        }
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            tbProgress.Text = "Canceled";
        }
        else if (e.Error != null)
        {
            tbProgress.Text = "Error: " + e.Error.Message;
        }
        else
        {
            tbProgress.Text = "Done";
        } 
    }

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        tbProgress.Text = e.ProgressPercentage.ToString() + "%";
    }

When application is deactivated, the thread wasn't closed, it is aborted and the exception occurs. How close threads with BackgroundWorker when application is deactivated?

like image 273
Aram Gevorgyan Avatar asked Oct 01 '11 12:10

Aram Gevorgyan


People also ask

What is the difference between BackgroundWorker and thread?

BackgroundWorker has already implemented functionality of reporting progress, completion and cancellation - so you don't need to implement it by yourself. Usage of Thread gives you more control over the async process execution (e.g. thread priority or choosing beetween foreground/background thread type).

How do I pause my background worker?

if you want to pause and resume a BGW, split your task into smaller packets (or put the needed values (like a counter variable/state) into e. Result), stop the BGW at a safe point and in the RunWorkerCompleted event, dispose the worker, instanciate it again (or a second BGW) and fire it up when needed.

Does BackgroundWorker use ThreadPool?

BackgroundWorker Class This class is essentially a wrapper for the ThreadPool class and uses a thread pool in its implementation.

Is BackgroundWorker threaded?

BackgroundWorker, is a component in . NET Framework, that allows executing code as a separate thread and then report progress and completion back to the UI.


1 Answers

When an app is deactivated, every thread other than the main UI thread will throw a ThreadAbortException as soon as it becomes active. This appears to be "by design" as a way of forcing apps to quickly stop what they are doing. Threads can catch the ThreadAbortException and wrap up what they are doing, but be aware that the ThreadAbortException will be automatically raised again at the end of the catch block. Any code in a finally block will also be executed.

For your specific issue, there's no reason to attempt to cancel the BackgroundWorker when the app is deactivated because the ThreadAbortException will occur and will effectively stop the background worker. If you want to do something to clean up when this occurs, you catch the ThreadAbortException in bw_DoWork, do what you need to do, and then let it die.

To get it to start again after activation, you would have to restart the background worker, just like you did the first time the app ran.

like image 57
PostalBatman Avatar answered Sep 28 '22 05:09

PostalBatman