Ciertos System.Threading.Tasks.Task
constructores toman a CancellationToken
como parámetro:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
Lo que me desconcierta acerca de esto es que no hay forma desde el interior del cuerpo del método para llegar realmente al token pasado (por ejemplo, nada parecido Task.CurrentTask.CancellationToken
). El token debe proporcionarse a través de algún otro mecanismo, como el objeto de estado o capturado en una lambda.
Entonces, ¿para qué sirve proporcionar el token de cancelación en el constructor?
Parallel.For
oParallel.ForEach
El constructor usa el token para el manejo de cancelación internamente. Si su código desea acceder al token, usted es responsable de pasárselo. Recomiendo leer el libro Programación en paralelo con Microsoft .NET en CodePlex .
Ejemplo de uso de CTS del libro:
fuente
token.ThrowIfCancellationRequested();
? En mi prueba, el comportamiento es el mismo. ¿Algunas ideas?when cts.Cancel() is called the Task is going to get canceled and end, no matter what you do
. Si la tarea se cancela antes de que haya comenzado, se cancela . Si el cuerpo de la Tarea simplemente nunca verifica ningún token, se ejecutará hasta su finalización, dando como resultado un estado RanToCompletion . Si el cuerpo arroja unOperationCancelledException
, p. Ej., PorThrowIfCancellationRequested
, entonces la Tarea verificará si el CancellationToken de esa Excepción es el mismo que el asociado con la Tarea. Si es así, la tarea se cancela . Si no, es culpable .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:
Cancelación en extensiones paralelas
fuente
Aquí hay un ejemplo que demuestra los dos puntos en la respuesta de Max Galkin :
Salida:
fuente