2010-07-15 2 views
5

У меня есть пользовательский интерфейс, отображающий статус длительных операций (загрузка некоторых текстовых файлов из ftp). Для моих целей я использую backgroundworker, и я не могу отменить операцию.Отменить 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); 
      } 

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

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

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

ответ

7

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

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

Необходимое решение должно быть получено от provider.Synchronize(); как-то.

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

+0

В качестве альтернативы, если возможно дать значение Synchronize a TimeOut, вы можете поместить синхронизацию в в то время как (! E.CancellationPending) privider.Synchronize (TimeOut); // если возможно цикл, продолжая функцию, которую вы сейчас используете. – greggorob64

2

Вы должны проверить e.Cancel в своем методе DoWork, который отсутствует в вашем фрагменте кода, но вы также должны изменить способ загрузки на асинхронный вызов, вы вызываете метод и дождитесь ответа в доковке. Это возможно, но он не будет проверять флаг отмены в среднее время.

Проверьте решение вы вывесили (линия 3):

void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while(!e.Cancel) 
    { 
     // do something 
    } 

    _resetEvent.Set(); // signal that worker is done 
} 
+0

Благодарим за внимание! Я понимаю вашу точку зрения, но мне нужно вообще использовать фонового рабочего? Я могу использовать async-операцию (как я это делал изначально) и использовать AutoResetEvent для отмены ... – Sharov

+0

Как указано в riffnl, «BackgroundWorker» поддерживает отмену. Вам не нужно использовать 'BackgroundWorker', но я рекомендую переместить * вверх * в абстракции в' Задача', а не * вниз * в абстракции для асинхронных делегатов. –

+0

@rifnl, это не e.Cancel. –

Смежные вопросы