Отмена фонового работника

c# .net multithreading

5934 просмотра

2 ответа

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

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

Нужен твой совет.

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

Автор: Sharov Источник Размещён: 12.11.2019 09:18

Ответы (2)


7 плюса

Решение

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

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

Решение, которое вам нужно, должно прийти provider.Synchronize();как-то.

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

Автор: Henk Holterman Размещён: 15.07.2010 01:01

2 плюса

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

Проверьте решение, которое вы разместили (строка 3):

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

    _resetEvent.Set(); // signal that worker is done 
} 
Автор: riffnl Размещён: 15.07.2010 12:34
32x32