Saltar al contenido

Compare usando Thread.Sleep y Timer para ejecución retrasada

Por fin después de mucho batallar hemos encontrado la solución de este rompecabezas que agunos lectores de nuestro espacio han presentado. Si tienes algo que compartir no dejes de aportar tu conocimiento.

Solución:

Una diferencia es que System.Threading.Timer envía la devolución de llamada a un subproceso del 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 montón de subprocesos (un proceso que consume muchos recursos, como señala el artículo al que hace referencia), ya que simplemente reutilice los subprocesos en el grupo, y si tiene más de un temporizador funcionando a la vez, significa que tendrá menos subprocesos ejecutándose a la vez (lo que también ahorra recursos considerables).

En otras palabras, Timer va a ser mucho más eficiente. También puede ser más preciso, ya que Thread.Sleep solo se garantiza que esperará AL MENOS el tiempo que especifique (el sistema operativo puede ponerlo en suspensión durante mucho más tiempo). Otorgada, Timer todavía no va a ser exactamente preciso, pero la intención es activar la devolución de llamada lo más cerca posible del tiempo especificado, mientras que esta NO es necesariamente la intención de Thread.Sleep.

En cuanto a destruir el Timerla devolución de llamada puede aceptar un parámetro, por lo que es posible que pueda pasar el Timer mismo como el parámetro y llame a Dispose en la devolución de llamada (aunque no lo he intentado, supongo que es posible que el temporizador se bloquee durante la devolución de llamada).

Editar: No, supongo que no puede hacer esto, ya que debe especificar el parámetro de devolución de llamada en el Timer constructor mismo.

¿Quizás algo como esto? (De nuevo, en realidad no lo he 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 evitar que la devolución de llamada del temporizador intente liberar el temporizador antes de la Timer habiendo sido establecido el campo.


Anexo: Como señaló el comentarista, si action() hace algo con la interfaz de usuario, luego usa un System.Windows.Forms.Timer es probablemente una mejor apuesta, ya que ejecutará la devolución de llamada en el subproceso de la interfaz de usuario. Sin embargo, si este no es el caso, y se debe a Thread.Sleep contra Threading.Timer, Threading.Timer es el camino a seguir.

usar ThreadPool.RegisterWaitForSingleObject en lugar de temporizador:

//Wait 5 seconds then print out to console. 
//You can replace AutoResetEvent with a Semaphore or EventWaitHandle if you want to execute the command on those events and/or the timeout
System.Threading.ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(false), (state, bTimeout) => Console.WriteLine(state), "This is my state variable", TimeSpan.FromSeconds(5), true);

Creo que Thread.Sleep está bien si realmente desea pausar la aplicación durante un período de tiempo específico. Creo que la razón por la que la gente dice que es un mal diseño es porque en la mayoría de las situaciones la gente no quiere que la aplicación se detenga.

Por ejemplo, estaba trabajando en un cliente pop3 donde el programador estaba usando Thread.Sleep(1000) para esperar mientras el socket recuperaba el correo. En esa situación, era mejor conectar un controlador de eventos al socket y continuar con la ejecución del programa después de que se completara el socket.

Tienes la opción de amparar nuestra función ejecutando un comentario y dejando una puntuación te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *