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.
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.
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.
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 ().
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With