2009-10-12 9 views

Respuesta

23

En primer lugar, ninguno de estos son buenos constructos de sincronización de subprocesos.

Primero, Thread.Abort dice "No me importa lo que estés haciendo, solo deja de hacerlo, y deja todo como está ahora". Básicamente es la forma de programación de decir "Hey, vencerlo". Si su hilo tiene archivos abiertos, esos archivos se dejarán abiertos hasta que la recolección de elementos no utilizados finalice la finalización de sus objetos.

Thread.Abort solo debe utilizarse, e incluso entonces probablemente, en el caso cuando el dominio de la aplicación en el que se está ejecutando el hilo se está derribando, preferiblemente solo cuando el proceso se termina.

En segundo lugar, Thread.Interrupt es una bestia bastante extraña. Básicamente dice "No me importa lo que estás esperando, deja de esperarlo". Lo extraño aquí es que si el hilo no está esperando nada, es "No me importa para qué vas a esperar, pero cuando lo hagas, deja de esperarlo de inmediato".

Ambas señales de que está imponiendo su voluntad a un hilo que no fue diseñado para que se le diga tales cosas.

Para abortar un hilo correctamente, el hilo debe revisar periódicamente algún tipo de indicador, ya sea una variable booleana simple volátil o un objeto de evento. Si la bandera dice "Ahora debe terminar", el hilo debe terminar por regresar de los métodos de manera ordenada.

Para reactivar correctamente un hilo, un hilo debe, en los lugares donde tiene que esperar para los objetos de sincronización, incluir un objeto "por favor, detenga la espera" que también espera. Así que, básicamente, lo haría ya sea para que el objeto que necesita se señalice, o el objeto "por favor detenga la espera" se señalice, determine cuál hizo y haga lo correcto.

Así que en lugar de Thread.Abort y Thread.Interrupt, se debe escribir el uso de hilos de objetos de sincronización normales, como eventos, exclusiones mutuas, semáforos, etc.

Por la misma razón, Thread.Suspend y Thread.Resume debe dejar solos , y también se han quedado obsoletas en las versiones posteriores de .NET.

10

A menos que usted está llamando Abort o Interrupt en el hilo de ejecución actual (como se hace ASP.NET para terminar una solicitud bruscamente, por ejemplo) que, básicamente, no se les puede llamar de una manera segura para los subprocesos.

Usa un WaitHandle o Monitor.Wait/Pulse para esperar de una manera que se pueda despertar. Solo deberías abortar otros hilos si estás destruyendo la aplicación, básicamente, ya que de lo contrario podrías terminar en un estado desconocido.

Consulte my article on graceful thread termination para ver un ejemplo de cómo hacerlo bien.

+0

Buen artículo Jon. ¿Cómo puedo encontrar tu webcast? – user186973

+0

@threadinglearner: ¿Qué webcast quieres decir? –

+0

Cualquier cosa sobre C# – user186973

2

Thread.Abort() genera una excepción ThreadAbortException en el hilo de destino. En general, se intenta forzar el final del hilo. No es una práctica recomendada para detener el procesamiento de un hilo.

Thread.Interrupt() interrumpe un hilo que está en estado WaitSleepJoin, esencialmente bloqueando un recurso como un WaitHandle. Esto permite que la persona que llama desbloquee el hilo.

Ninguno de los dos es realmente "seguro para subprocesos", en el sentido de que están específicamente destinados a afectar el comportamiento de los hilos de una manera que es difícil de predecir.

En general, se recomienda utilizar objetos de sincronización (como WaitHandles o Semaphores) para permitir que los hilos se sincronicen de forma segura entre sí.

1

La diferencia entre Abortar e Interrumpir es que si bien ambos lanzarán una excepción (ThreadAbortException y ThreadInterruptException), al llamar Abort se volverá a lanzar la excepción al final del bloque catch y se asegurará de finalizar el hilo en ejecución.

Cuestiones relacionadas