2010-07-12 7 views
0

Обычно, когда я хочу, чтобы отменить BackgroundWorker в C# я буду делать что-то вроде этого:C# BackgroundWorker Отмена с вспомогательной функцией

 while (backgroundWorker1.IsBusy) 
    { 
     backgroundWorker1.CancelAsync(); 
     autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 

в одном приложении есть ряд backgroundWorkers. Действительно ли полезно использовать вспомогательную функцию для отмены фоновых рисунков, например?

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are) 
{ 
    while (bgw.IsBusy) 
    { 
     bgw.CancelAsync(); 
     are.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 
} 

Меня беспокоит то, что вместо передачи объектов в вопросе в функции, копии сделаны, тем самым поражение цели иметь функцию. Основная цель использования этой функции - уменьшить кодовое пространство и сделать код приложения более удобочитаемым/поддерживаемым.

ответ

2

Нет, это не нормально. Это вызывает тупик, когда BGW имеет обработчик события RunWorkerCompleted. Этот обработчик не может работать до тех пор, пока основной поток не перейдет в режим ожидания и не войдет в цикл сообщений. Свойство IsBusy останется True до тех пор, пока обработчик этого события не завершится.

У вас есть тайм-аут по вызову WaitOne, поэтому, по крайней мере, ваша программа не будет полностью висеть. Но когда WaitOne() возвращается, BGW не еще не завершен, обработчик события RWC еще не запущен. Единственная практическая альтернатива для обработчика событий RWC - делать все, что необходимо, когда завершение аннулирования завершено.

+0

Вот и все! Благодаря! –

0

Ваш код является неправильным.

Вызов CancelAsync просто устанавливает CancellationPending flag на BackgroundWorker на true. Ожидается, что ваш код в событии DowWork будет периодически проверять этот флаг и останавливаться, если флаг равен true.

Вызов CancelAsync много раз не принесет пользы, и не должно быть никаких причин замораживать нить пользовательского интерфейса, пока он фактически не отменяется.

+0

Да, я это понимаю. У моего фонового рабочего есть проверки в нем, чтобы искать backgroundWorker1.CancellationPending и выйти соответственно. Мой вопрос более близок к тому, что флаги backgroundWorker1 будут заданы вспомогательной функцией или он собирается установить флаги копии backgroundWorker, которая уничтожается при возврате функции. –

+0

Поскольку класс 'BackgroundWorker' не является структурой, нет. Все классы C# всегда передаются по ссылке. Однако функция бесполезна. – SLaks

+0

Классы передаются по значению, если не используется ключевое слово ref или out. Для ссылочных типов передается копия справки. –