Considere un método hipotético de un objeto que hace cosas por usted:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
¿Cómo se puede esperar a que se realice un BackgroundWorker?
En el pasado la gente ha intentado:
while (_worker.IsBusy)
{
Sleep(100);
}
Pero esto se interrumpe , porque IsBusy
no se borra hasta después de RunWorkerCompleted
que se maneja el evento, y ese evento no se puede manejar hasta que la aplicación quede inactiva. La aplicación no estará inactiva hasta que el trabajador haya terminado. (Además, es un circuito ocupado, desagradable).
Otros han agregado sugerencias para incluirlo en:
while (_worker.IsBusy)
{
Application.DoEvents();
}
El problema con esto es que Application.DoEvents()
hace que se procesen los mensajes actualmente en la cola, lo que causa problemas de reincorporación (.NET no es reentrante).
Espero usar alguna solución que involucre objetos de sincronización de eventos, donde el código espera un evento, que los RunWorkerCompleted
manejadores de eventos del trabajador establecen. Algo como:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Pero volví al punto muerto: el controlador de eventos no puede ejecutarse hasta que la aplicación esté inactiva, y la aplicación no estará inactiva porque está esperando un Evento.
Entonces, ¿cómo puedes esperar a que termine un BackgroundWorker?
Actualización La gente parece estar confundida por esta pregunta. Parecen pensar que usaré el BackgroundWorker como:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Es decir , no se, es decir , no lo que estoy haciendo, y que es no lo que se pide aquí. Si ese fuera el caso, no tendría sentido usar un trabajador de fondo.