usar tareas puede paralelas operadores metodo hilos ejemplo ejecutar carece await async asincrono c# .net-4.0 task-parallel-library cancellation-token

c# - puede - Token de cancelación en el constructor de tareas: ¿por qué?



no se puede usar await en void (3)

El constructor utiliza el token para el manejo de la cancelación internamente. Si su código desea acceder al token, usted es responsable de pasárselo. Recomiendo encarecidamente leer el libro de Programación Paralela con Microsoft .NET en CodePlex .

Ejemplo de uso de CTS del libro:

CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken token = cts.Token; Task myTask = Task.Factory.StartNew(() => { for (...) { token.ThrowIfCancellationRequested(); // Body of for loop. } }, token); // ... elsewhere ... cts.Cancel();

Ciertos System.Threading.Tasks.Task constructores toman un CancellationToken como parámetro:

CancellationTokenSource source = new CancellationTokenSource(); Task t = new Task (/* method */, source.Token);

Lo que me desconcierta de esto es que no hay forma desde dentro del cuerpo del método para obtener el token pasado (por ejemplo, nada como Task.CurrentTask.CancellationToken ). El token debe proporcionarse a través de algún otro mecanismo, como el objeto de estado o capturado en un lambda.

Entonces, ¿para qué sirve proporcionar el token de cancelación en el constructor?


La cancelación no es un caso simple como muchos podrían pensar. Algunas de las sutilezas se explican en esta publicación de blog en msdn:

Por ejemplo:

En ciertas situaciones en Extensiones paralelas y en otros sistemas, es necesario activar un método bloqueado por razones que no se deben a la cancelación explícita por parte de un usuario. Por ejemplo, si un subproceso está bloqueado en blockCollection.Take () debido a que la colección está vacía y luego otro subproceso llama a BloquearCollection.CompleteAdding (), entonces la primera llamada debería activarse y lanzar una excepción InvalidOperationException para representar un uso incorrecto.

http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx


Pasar este token al constructor de tareas lo asocia con esta tarea.

Citando la respuesta de Stephen Toub de MSDN :

Esto tiene dos beneficios principales:

  1. Si el token ha solicitado la cancelación antes de que la Tarea comience a ejecutarse, la Tarea no se ejecutará. En lugar de pasar a la Ejecución, se pasará inmediatamente a Cancelado. Esto evita los costos de ejecutar la tarea si solo se cancela mientras se ejecuta de todos modos.
  2. Si el cuerpo de la tarea también está monitoreando el token de cancelación y lanza una OperationCanceledException que contiene ese token (que es lo que hace ThrowIfCancellationRequested), entonces cuando la tarea ve esa OCE, verifica si el token de OCE coincide con el token de la Tarea. Si lo hace, esa excepción se considera un acuse de recibo de cancelación cooperativa y la Tarea pasa al estado Cancelado (en lugar de al estado Con fallo).