Considérons un hypothétique d'un objet qui fait des choses pour vous :
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Comment peut-on attendre qu'un BackgroundWorker soit terminé ?
Dans le passé, les gens ont essayé :
while (_worker.IsBusy)
{
Sleep(100);
}
Mais cela bloque parce que IsBusy
n'est pas effacée avant que le RunWorkerCompleted
est traité, et cet événement ne peut pas être traité tant que l'application n'est pas au repos. L'application ne sera pas inactive tant que le travailleur n'aura pas terminé. (De plus, c'est une boucle occupée - dégoûtant).
D'autres ont suggéré de l'ajouter :
while (_worker.IsBusy)
{
Application.DoEvents();
}
Le problème avec ça, c'est que c'est Application.DoEvents()
entraîne le traitement des messages actuellement dans la file d'attente, ce qui pose des problèmes de ré-entrance (.NET n'est pas ré-entrant).
J'espère pouvoir utiliser une solution impliquant des objets de synchronisation d'événements, où le code attend pour un événement - que le travailleur RunWorkerCompleted
les jeux de gestionnaires d'événements. Quelque chose comme :
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Mais je suis de nouveau dans l'impasse : le gestionnaire d'événements ne peut pas s'exécuter tant que l'application n'est pas au repos, et l'application ne se met pas au repos parce qu'elle attend un événement.
Alors comment attendre la fin d'un BackgroundWorker ?
Mise à jour Les gens semblent être désorientés par cette question. Ils semblent penser que je vais utiliser le BackgroundWorker comme.. :
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
C'est-à-dire pas c'est-à-dire pas ce que je fais, et c'est pas ce qui est demandé ici. Si c'était le cas, il n'y aurait aucun intérêt à utiliser un travailleur de fond.