c# - Matando un hilo.NET
multithreading abort (7)
No llame a Thread.Abort()
!
Thread.Abort
. El Thread.Abort
es peligroso. En su lugar, debe cooperar con el hilo para que pueda cerrarse pacíficamente. El hilo debe diseñarse para que se le diga que se mate a sí mismo, por ejemplo, al tener un keepGoing
booleano keepGoing
que configuró como falso cuando desea que el hilo se detenga. El hilo tendría entonces algo como
while (keepGoing)
{
/* Do work. */
}
Si el subproceso puede bloquearse en un modo de Wait
o Wait
entonces puede salir de esas funciones llamando a Thread.Interrupt()
. El hilo debe estar preparado para manejar una ThreadInterruptedException
:
try
{
while (keepGoing)
{
/* Do work. */
}
}
catch (ThreadInterruptedException exception)
{
/* Clean up. */
}
He creado un hilo ejecutando un determinado método. Pero a veces me gustaría matar el hilo incluso si todavía está funcionando. ¿Cómo puedo hacer esto? Intenté Thread.Abort () pero aparece un cuadro de mensaje que dice "Thread aborted". ¿Qué tengo que hacer?
Abortar un hilo es una muy mala idea, ya que no se puede determinar qué estaba haciendo el hilo en el momento de la cancelación.
En su lugar, tenga una propiedad que el hilo pueda verificar y que su código externo pueda configurar. Deje que el hilo revise esta propiedad booleana cuando esté en un lugar seguro para salir.
Deberías llamar a Abort () como último recurso. Puedes usar una variable para sincronizar este hilo en su lugar:
volatile bool shutdown = false;
void RunThread()
{
while (!shutdown)
{
...
}
}
void StopThread()
{
shutdown = true;
}
Esto permite que su hilo termine limpiamente lo que estaba haciendo, dejando su aplicación en un estado de buena reputación.
Estoy de acuerdo con Jon B
volatile bool shutdown = false;
void RunThread()
{
try
{
while (!shutdown)
{
/* Do work. */
}
}
catch (ThreadAbortException exception)
{
/* Clean up. */
}
}
void StopThread()
{
shutdown = true;
}
La forma más correcta y segura de subprocesos es usar WaitHandle para señalar al hilo cuando se supone que debe detenerse. Principalmente utilizo ManualResetEvent.
En tu hilo, puedes tener:
private void RunThread()
{
while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
{
// ...
}
}
donde this.flag
es una instancia de ManualResetEvent. Esto significa que puede llamar a this.flag.Set()
desde fuera del hilo para detener el bucle.
El método WaitOne solo devolverá verdadero cuando se establece el indicador. De lo contrario, expirará después del tiempo de espera especificado (100 ms en el ejemplo) y el hilo se ejecutará a través del bucle una vez más.
No es una buena idea matar un hilo. Es mejor señalar que debe detenerse y dejar que termine con gracia. Hay varias formas diferentes de hacer esto.
- Use
Thread.Interrupt
paraThread.Interrupt
si está bloqueado. - Encuesta una variable de bandera.
- Utilice la clase
WaitHandle
para enviar una señal.
No es necesario que repita cómo se puede usar cada método, ya que ya lo he hecho en esta respuesta .
También hay ejemplos de matar hilos en mi clase de servidor web ...
https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948
Yo diría que Abort está bien, simplemente entienda cuáles son las ramificaciones ... siempre y cuando esté indicando el estado antes de que Abort funcione de forma prolongada, pero se requieren indicadores como (ShouldStop o ActionBranch, etc.)
¡Échale un vistazo a los ejemplos!