Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel backgroundworker

I have UI which displaying status of long-running operations (downloading some text files from ftp) . For my purposes I use backgroundworker and I can't cancel operation.

void worker_DoWork( object sender, DoWorkEventArgs e )
    {

        try
        {
            int rowIndex = (int)e.Argument;

            //begin UI update
            StartWaitingBar(rowIndex);
            //get provider id cell
            GridViewDataRowInfo row = _proivderGridView.Rows[rowIndex];
            GridViewCellInfo provIdCell = row.Cells[ "ProviderId" ];

            var providerData = GetProviderData(Convert.ToInt32( provIdCell.Value));
            var provider =  ProviderFactory.CreateProvider(providerData);
            provider.Synchronize();
            e.Result = rowIndex;

        }
        catch (Exception exception)
        {
           return;
        }
    }

And code for worker creation:

           BackgroundWorker worker = new BackgroundWorker();
           worker.DoWork += worker_DoWork;
           worker.RunWorkerCompleted += worker_RunWorkerCompleted;
           worker.WorkerSupportsCancellation = true;
           worker.RunWorkerAsync(args.RowIndex);
          _syncWorkers.Add(providerId,worker);
           ...
            var worker = _syncWorkers[providerId];

            if(worker.IsBusy)
             {
                 worker.CancelAsync();
             }
            else
            {
                worker.RunWorkerAsync(args.RowIndex);
            }   

Solution provided here seems not working for me beacuse it works for recurring operations (for which background worker is created, I suppose). Do I have to use threads(abort and join) for my purposes because I should provide possibilities for user to cancel long-running operation?

Need your advice.

Thanks in advance.

like image 789
Sharov Avatar asked Jul 15 '10 12:07

Sharov


People also ask

How to add cancellation support to backgroundworker?

So to sum up, adding cancellation support to your BackgroundWorker is easy - just make sure that you set WorkerSupportsCancellation property to true and check the CancellationPending property while performing the work. Then, when you want to cancel the task, you just have to call the CancelAsync () method on the worker and you're done.

How to cancel a long running I/O action in backgroundworker?

You cannot use Backgroundworker.CancelAsync () to cancel a long running I/O action. Like rifnl answered, the DoWork has to check worker.CancellationPending and set e.Cancel. But you shouldn't use Thread.Abort () either. It could destabilize your process. The solution you need has to come from provider.Synchronize (); somehow.

How to stop a backgroundworker from running?

You will have to use a flag shared between the main thread and the BackgroundWorker, such as BackgroundWorker.CancellationPending. When you want the BackgroundWorker to exit, just set the flag using BackgroundWorker.CancelAsync ().

What is the backgroundworker object?

NET has made the BackgroundWorker object available to us to simplify threading. This object is designed to simply run a function on a different thread and then call an event on your UI thread when it's complete.


1 Answers

You cannot use Backgroundworker.CancelAsync() to cancel a long running I/O action. Like rifnl answered, the DoWork has to check worker.CancellationPending and set e.Cancel.

But you shouldn't use Thread.Abort() either. It could destabilize your process.

The solution you need has to come from provider.Synchronize(); somehow.

PS: and catch { return; } is horrible. Remove the entire try/catch and let the Bgw handle exceptions.

like image 72
Henk Holterman Avatar answered Sep 18 '22 01:09

Henk Holterman