Considérez une méthode 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 attendre qu'un BackgroundWorker soit terminé?
Dans le passé, les gens ont essayé:
while (_worker.IsBusy)
{
Sleep(100);
}
Mais ce blocage , car il IsBusy
n'est résolu qu'après la RunWorkerCompleted
gestion de l' événement, et cet événement ne peut pas être géré tant que l'application n'est pas inactive. L'application ne restera pas inactive tant que le worker n'aura pas terminé. (De plus, c'est une boucle occupée - dégoûtant.)
D'autres ont ajouté des suggestions de kludging dans:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Le problème avec cela est que cela Application.DoEvents()
provoque le traitement des messages actuellement dans la file d'attente, ce qui provoque des problèmes de réentrée (.NET n'est pas rentrant).
J'espère utiliser une solution impliquant des objets de synchronisation d'événements, où le code attend un événement - que les RunWorkerCompleted
gestionnaires d'événements du travailleur définissent. 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 retour à l'impasse: le gestionnaire d'événements ne peut pas s'exécuter tant que l'application n'est pas inactive, et l'application ne sera pas inactive car elle attend un événement.
Alors, comment pouvez-vous attendre qu'un BackgroundWorker se termine?
Mise à jour Les gens semblent confus par cette question. Ils semblent penser que j'utiliserai BackgroundWorker comme:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Ce n'est pas ça, ce n'est pas ce que je fais et ce n'est pas ce qu'on demande ici. Si tel était le cas, il ne servirait à rien d'utiliser un travailleur d'arrière-plan.