Considere um método hipotético de um objeto que faz coisas para você:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Como alguém pode esperar que um BackgroundWorker seja executado?
No passado, as pessoas tentaram:
while (_worker.IsBusy)
{
Sleep(100);
}
Mas esses bloqueios , porque IsBusy
não são limpos até que o RunWorkerCompleted
evento seja tratado e esse evento não pode ser tratado até que o aplicativo fique ocioso. O aplicativo não ficará ocioso até que o trabalhador termine. (Além disso, é um loop ocupado - nojento.)
Outros adicionaram sugestões de críticas a:
while (_worker.IsBusy)
{
Application.DoEvents();
}
O problema é que isso faz Application.DoEvents()
com que as mensagens atualmente na fila sejam processadas, o que causa problemas de reentrada (o .NET não é reentrante).
Espero usar alguma solução que envolva objetos de sincronização de eventos, onde o código aguarda um evento - RunWorkerCompleted
definido pelos manipuladores de eventos do trabalhador . Algo como:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Mas estou de volta ao impasse: o manipulador de eventos não pode ser executado até que o aplicativo fique ocioso e o aplicativo não ficará ocioso porque está aguardando um Evento.
Então, como você pode esperar que um BackgroundWorker termine?
Atualizar As pessoas parecem estar confusas com esta pergunta. Eles parecem pensar que vou usar o BackgroundWorker como:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Não é isso, não é o que estou fazendo e não é o que está sendo perguntado aqui. Se fosse esse o caso, não faria sentido usar um trabalhador em segundo plano.