2011-03-02 7 views
10

Tengo una tarea que debo cancelar si se agota el tiempo de espera. Por ejemploCancelar una tarea

var t = Task.Factory.StartNew(() => 
{ 
    Thread.Sleep(5000) // some long running task 
    "do something" 
}); 
Task.WaitAll(new[] {t}, 1000); 

Pero parece que la tarea aún sigue funcionando. Traté de usar CancellationTokenSource, pero eso tampoco parecía funcionar.

me confirmó esto utilizando el siguiente fragmento de

static void Main(string[] args) 
     { 
      var cancellationTokenSource = new CancellationTokenSource(); 

      var t = Task.Factory.StartNew(() => { 
       Thread.Sleep(5000); 
       Console.WriteLine("Still working"); 
      }, cancellationTokenSource.Token); 

      Task.WaitAll(new[] {t}, 1000); 

      cancellationTokenSource.Cancel(); 

      Console.ReadLine(); 
     } 

La consola despliega "Todavía trabajo". Pensé que la tarea habría sido cancelada.

Estoy seguro de que me falta algo. ¿Qué me estoy perdiendo? Gracias.

Respuesta

29

Los tokens de cancelación no cancelan mágicamente nada. Solo permiten verificar la cancelación de manera estandarizada, p. Ej. a través de ThrowIfCancellationRequested.

Por lo general, tendría alguna tarea que necesita realizar un montón de trabajo. Periódicamente llama al ThrowIfCancellationRequested, y luego cualquier código que necesite cancelar la tarea llamará al Cancel en el CancellationTokenSource cuando sea necesario. La tarea se lanzará cuando vuelva a verificar la cancelación, y todo estará bien.

Parece que está buscando una cancelación no cooperativa, y eso sería peligroso, por exactamente las mismas razones por las que la normal Thread.Abort es peligrosa. Es más limpio dejar que la tarea elija los puntos en los que se permitirá cancelar.

Cuestiones relacionadas