У меня есть UI который, отображая состояние продолжительных операций (загружающий некоторые текстовые файлы с ftp). В моих целях я использую backgroundworker, и я не могу отменить операцию.
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;
}
}
И код для создания рабочего:
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);
}
Решение, предоставленное здесь, кажется не работой для меня, потому что это работает на повторяющиеся операции (для которого создается второстепенный рабочий, я предполагаю). Я должен использовать потоки (аварийное прекращение работы и соединение) в моих целях, потому что я должен предоставить возможности пользователю отменить продолжительную операцию?
Нужен Ваш совет.
Заранее спасибо.
Вы не можете использовать Backgroundworker.CancelAsync ()
для отмены длительного действия ввода-вывода. Как и ответил rifnl, DoWork должен проверить worker.CancellationPending
и установить e.Cancel
.
Но вы также не должны использовать Thread.Abort ()
. Это может дестабилизировать ваш процесс.
Решение, которое вам нужно, должно каким-то образом исходить от Providerr.Synchronize ();
.
PS: и catch {return; }
ужасно. Удалите все try / catch и позвольте Bgw обрабатывать исключения.
Вам нужно проверить e.Cancel внутри вашего метода DoWork, который отсутствует в вашем code-snippet, но вам также нужно изменить ваш метод загрузки на асинхронный вызов, вы вызываете метод и ждете ответа внутри dowork. Это возможно, но это не будет проверять флаг отмены в это время.
Проверьте решение, которое вы опубликовали (строка 3):
void worker_DoWork(object sender, DoWorkEventArgs e)
{
while(!e.Cancel)
{
// do something
}
_resetEvent.Set(); // signal that worker is done
}