Tareas periódicas cancelables en .NET Framework 4.0

La creación de tareas periódicas cancelables en .NET Framework 4.0 no es tan sencillo como en versiones posteriores del framework .NET.

Existen ocasiones en las que deseamos realizar una tarea que lleva un gran esfuerzo de forma asíncrona sin bloquear  el hilo principal en el que se está ejecutando nuestra aplicación, para ello a partir de .NET 4.5, simplemente podemos utilizar   un

 

    await Task.Delay(TIEMPO_REPETICION);

 

Pero en el framework NET 4.0, esta opción no está disponible, por eso entre otras soluciones, podemos

utilizar un temporizador, en concreto un

 System.Timers.Timer

Inicalizar la tarea, Task

Lo primero que haremos será inicializar una nueva tarea utilizando la funcionalidad proporcionada por la factoría Task.Factory

 

     Task.Factory.StartNew(() => { TareaAIniciar(); });

 

Cancelación

Ahora bien, a esta TareaAInicar, se le puede pasar un token de cancelación, un objeto al que se le puede invocar un método Cancel

    Task.Factory.StartNew(() => { TareaAIniciar(tokenCancelacion); });

 

De este modo, en cualquier momento podemos acceder a su propiedad IsCancellationRequested,

            
  if (cancellationToken.IsCancellationRequested)
              {
                  Console.WriteLine("Task Cancel was received, throwing exception, ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
                    cancellationToken.ThrowIfCancellationRequested();
                }

 

    El timer

Este objeto  System.Timers.Timer, una vez iniciado (Start) , genera un evento (Elapsed) en intervalos regulares.

var newTimer = new System.Timers.Timer(intervalInMilliseconds);

newTimer.Elapsed += (sender, e) => action(cancellationToken);

newTimer.Start();

cancellationToken.Register(() =>

{

newTimer.Close();

});

 

Declararemos nuestro método que queremos que corra en otro hilo, este método al final tiene una signatura del tipo Action<CancellationToken>

 

            

private static void LongRunningWork(CancellationToken cancellationToken)

{

if (cancellationToken.IsCancellationRequested == true)

{

Console.WriteLine("Task finished before start, ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);

cancellationToken.ThrowIfCancellationRequested();

}

 

//Do Work Here

}

Iniciar el timer

Declaramos el método que inicia el timer

 

            


private static void RepeatActionOnInterval(int intervalInMilliseconds, CancellationToken cancellationToken, Action<CancellationToken> action)

{

if (cancellationToken.IsCancellationRequested == true)

{

Console.WriteLine("Task cancelled before start, ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);

cancellationToken.ThrowIfCancellationRequested();

}

if (intervalInMilliseconds > Timeout.Infinite)

{

var newTimer = new System.Timers.Timer(intervalInMilliseconds);

newTimer.Elapsed += (sender, e) => action(cancellationToken);

newTimer.Start();

cancellationToken.Register(() =>

{

newTimer.Close();

});

}

else

{

action(cancellationToken);

}

}

Y por último, lo invocamos

            

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

Task periodicTask = Task.Factory.StartNew(() =>

{

RepeatActionOnInterval(intervalMiliseconds, cancellationTokenSource.Token, LongRunningWork);

});

Deja un comentario

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar