Planteamiento del problemala forma de terminar un subproceso de trabajo correctamente en C#
Tengo un subproceso de trabajo que básicamente explora una carpeta, de entrar en los archivos dentro de ella, y luego se duerme durante un tiempo. La operación de escaneo puede tomar de 2 a 3 segundos, pero no mucho más. Estoy buscando una manera de detener este hilo elegantemente.
Aclaración: Quiero detener el hilo, mientras que es dormir, y no mientras que es de exploración. Sin embargo, el problema es que no sé cuál es el estado actual del hilo. Si está durmiendo, quiero que salga inmediatamente. Si está escaneando, quiero que salga en el momento en que intenta bloquearlo.
Los intentos de una solución
Al principio estaba usando sueño y de alarma. Luego descubrí que interrumpir realmente no interrumpe el sueño, solo funciona cuando los hilos intentan entrar en modo de suspensión.
Así que cambié a Monitor Wait & Pulse. Luego descubrí que el Pulso solo funciona cuando estoy realmente en Espera. Así que ahora tengo un hilo que se ve así:
while (m_shouldRun)
{
try
{
DoSomethingThatTakesSeveralSeconds();
lock (this)
{
Monitor.Wait(this, 5000);
}
}
catch (ThreadInterruptedException)
{
m_shouldRun = false;
}
}
Y ahora tengo que crear mi función Detener. Así que empecé con:
public void Stop()
{
m_shouldRun = false;
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
Pero esto no funciona porque se me puede pulsante mientras que las obras de hilo (si bien no está esperando). Por lo que añade interrupción:
public void Stop()
{
m_shouldRun = false;
thread.Interrupt();
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
Otra opción es utilizar:
public void Stop()
{
m_shouldRun = false;
while (!thread.Join(1000))
{
lock (this)
{
Monitor.Pulse(this);
}
}
}
La pregunta
¿Cuál es el método preferido? ¿Hay un tercer método que sea preferible?
"* Al principio yo estaba usando sueño y de interrupción Luego descubrí que Interrupt realmente no interrumpe el Sueño, solo funciona cuando los hilos INTENTAN entrar a dormir. * "Eso es extraño. ¿Es esto un error conocido? Si no es así, ¿puedes tratar de reproducirlo con un ejemplo de juguete? – Heinzi