Отмена backgroundworker

У меня есть 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);
            }   

Решение, предоставленное здесь, кажется не работой для меня, потому что это работает на повторяющиеся операции (для которого создается второстепенный рабочий, я предполагаю). Я должен использовать потоки (аварийное прекращение работы и соединение) в моих целях, потому что я должен предоставить возможности пользователю отменить продолжительную операцию?

Нужен Ваш совет.

Заранее спасибо.

5
задан Community 23 May 2017 в 11:50
поделиться

2 ответа

Вы не можете использовать Backgroundworker.CancelAsync () для отмены длительного действия ввода-вывода. Как и ответил rifnl, DoWork должен проверить worker.CancellationPending и установить e.Cancel .

Но вы также не должны использовать Thread.Abort () . Это может дестабилизировать ваш процесс.

Решение, которое вам нужно, должно каким-то образом исходить от Providerr.Synchronize (); .

PS: и catch {return; } ужасно. Удалите все try / catch и позвольте Bgw обрабатывать исключения.

7
ответ дан 14 December 2019 в 01:00
поделиться

Вам нужно проверить 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 
} 
2
ответ дан 14 December 2019 в 01:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: