En una aplicación que estoy desarrollando, tengo un formulario principal que simplemente se sienta allí y muestra datos de registro, y un hilo de trabajo que realiza el trabajo de forma autónoma en un bucle.Cierre con gracia un hilo
MyWorker worker = new MyWorker();
MainForm mainForm = new MainForm();
// Subscribe form to log event so log data gets displayed
worker.Log += mainForm.Log;
// Start the worker thread's MainLoop
new Thread(new ThreadStart(worker.MainLoop)).Start();
// Show the form (blocking)
Application.Run(mainForm);
// If we end up here, the form has been closed and the worker has to stop running
worker.Running = false;
Como puede ver, cada vez que se cierra el formulario, el hilo de trabajo debe detenerse. El trabajador tiene el siguiente aspecto:
public class MyWorker
{
public String Running { get; set; }
public MyWorker()
{
Running = true;
}
public void MainLoop()
{
while (Running)
{
DoExtensiveWork1();
if (!Running) return;
DoExtensiveWork2();
if (!Running) return;
DoExtensiveWork3();
if (!Running) return;
DoExtensiveWork4();
if (!Running) return;
DoExtensiveWork5();
if (!Running) return;
// We have to wait fifteen minutes (900 seconds)
// before another "run" can be processed
for (int i = 0; i < 900; i++)
{
Thread.Sleep(1000);
if (!Running) return;
}
}
}
}
Como se puede ver, quiero que el hilo sea capaz de parar cuando se cambia entre sucesivas operaciones de trabajo, pero no cuando dentro de una operación. Cuando finaliza una operación (DoExtensiveWorkN
), su estado y resultados se mantienen en el disco o la base de datos, por lo que salir mientras una operación está en progreso (por ejemplo, Thread.Abort
) no es una opción.
Sin embargo, creo que este código que acabo de escribir es repulsivo, especialmente el "bucle de espera" que duerme 900 segundos para evitar que el hilo funcione durante 15 minutos antes de detectar Running
se ha configurado para false
.
Prefiero ser capaz de lanzar algún tipo de evento para detener el ciclo principal tan pronto como haya terminado un trabajo.
¿Alguien puede indicarme en la dirección correcta cómo hacer esto, o si se requiere una reescritura total porque entiendo completamente el enhebrado, muéstreme en algún lugar donde se explican esos principios?
Los temporizadores no resolverán el problema principal que tengo: no quiero que el trabajo continúe cuando se cierre el formulario, y no quiero agregar mucho código para seguir buscando eso. – CodeCaster
@CodeCaster: Ah, malentendí "por lo que dejar de fumar mientras una operación está en progreso (por ejemplo, Thread.Abort) no es una opción" para significar todo el hilo. Mi pensamiento entonces sería usar una variedad de Acciones pero Iridium me ganó. Todavía prefiero el temporizador para la espera de 15 minutos. :) – Chris
Podría haberlo descrito más claramente. Gracias por la sugerencia, sin embargo. :-) – CodeCaster