2010-05-31 15 views
5

Estoy tratando de implementar un hilo de trabajo cancelable utilizando las nuevas construcciones de subprocesamiento en el espacio de nombres System.Threading.Tasks. Hasta ahora me han han llegado con esta implementación:Cómo implementar hilo de trabajo cancelable

public sealed class Scheduler 
{ 
    private CancellationTokenSource _cancellationTokenSource; 
    public System.Threading.Tasks.Task Worker { get; private set; } 

    public void Start() 
    { 
     _cancellationTokenSource = new CancellationTokenSource(); 

     Worker = System.Threading.Tasks.Task.Factory.StartNew(
      () => RunTasks(_cancellationTokenSource.Token), 
      _cancellationTokenSource.Token 
     ); 
    } 

    private static void RunTasks(CancellationToken cancellationToken) 
    { 
     while (!cancellationToken.IsCancellationRequested) 
     { 
      Thread.Sleep(1000); // simulate work 
     } 
    } 

    public void Stop() 
    { 
     try 
     { 
      _cancellationTokenSource.Cancel(); 
      Worker.Wait(_cancellationTokenSource.Token); 
     } 
     catch (OperationCanceledException) 
     { 
      // OperationCanceledException is expected when a Task is cancelled. 
     } 
    } 
} 

Cuando vuelve Stop() espero Worker.Status ser TaskStatus.Canceled.
Las pruebas de mi unidad han demostrado que bajo ciertas condiciones Worker.Status permanece configurado en TaskStatus.Running.

¿Es esta la manera correcta de implementar un hilo de trabajo cancelable?

Respuesta

5

yo creo que el problema está en su llamada a

Worker.Wait(_cancellationTokenSource.Token); 

que está esperando para el token de debe señalizarse - que ya es, porque has acaba de llamar Cancel(). Si pasa a solo

Worker.Wait(); 

entonces creo que usted verá un estado de RanToCompletion. No verá Cancelado, porque su tarea no está lanzando OperationCanceledException. Si cambia de método RunTasks llamar

cancellationToken.ThrowIfCancellationRequested() 

al final, a continuación, tendrá que coger un AggregateException en Stop - pero luego verá un estado de Canceled al final.

Al menos, eso es lo que muestra mi experimentación :)

+0

Sí, eso solucionó el problema. Gracias. –

Cuestiones relacionadas