Una diferencia es que System.Threading.Timer distribuye la devolución de llamada en un subproceso de grupo de subprocesos, en lugar de crear un nuevo subproceso cada vez. Si necesita que esto suceda más de una vez durante la vida de su aplicación, esto ahorrará la sobrecarga de crear y destruir un grupo de hilos (un proceso que consume muchos recursos, como señala el artículo que referencia), ya que lo hará solo reutilice los hilos en el grupo, y si va a tener más de un temporizador funcionando a la vez, significa que tendrá menos hilos ejecutándose al mismo tiempo (lo que también ahorrará considerables recursos).
En otras palabras, Timer va a ser mucho más eficiente. También puede ser más preciso, ya que Thread.Sleep solo garantiza que esperará al menos el tiempo que especifique (el sistema operativo puede ponerlo a dormir durante mucho más tiempo). De acuerdo, Timer aún no será exactamente exacto, pero la intención es disparar la devolución de llamada lo más cerca posible del tiempo especificado, mientras que NO es necesariamente la intención de Thread.Sleep.
En cuanto a la destrucción del temporizador, la devolución de llamada puede aceptar un parámetro, por lo que puede pasar el temporizador como parámetro y llamar a Dispose en la devolución de llamada (aunque no lo he probado, supongo que es es posible que el temporizador se bloquee durante la devolución de llamada).
Editar: No, supongo que no puede hacer esto, ya que tiene que especificar el parámetro de devolución de llamada en el propio constructor del temporizador.
Quizás algo como esto? (De nuevo, en realidad no han probado)
class TimerState
{
public Timer Timer;
}
... y para iniciar el temporizador:
TimerState state = new TimerState();
lock (state)
{
state.Timer = new Timer((callbackState) => {
action();
lock (callbackState) { callbackState.Timer.Dispose(); }
}, state, millisecond, -1);
}
El bloqueo debe impedir la devolución de llamada del temporizador de tratar de liberar el temporizador antes de que el temporizador campo que se ha establecido.
Adición: Como el comentarista señaló, si la acción() hace algo con la interfaz de usuario, y luego usando un System.Windows.Forms.Timer es probablemente una mejor opción, ya que se ejecutará la devolución de llamada en la interfaz de usuario hilo. Sin embargo, si este no es el caso, y depende de Thread.Sleep vs. Threading.Timer, Threading.Timer es el camino a seguir.
También vale la pena señalar la diferencia con System.Windows.Forms.Timer, que I * believe * llama a una función en el subproceso UI, que es realmente importante para las aplicaciones WinForms. –
Para lectores futuros, 'Sleep' no garantiza que el evento sea POR LO MENOS, está documentado que podría ser menor. –
Por curiosidad ... ¿dónde está eso documentado? –