Cancelación de ficha en el constructor de la tarea: ¿por qué?
-
02-10-2019 - |
Pregunta
Ciertos constructores System.Threading.Tasks.Task
tomar un CancellationToken
como un parámetro:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
Lo que me desconcierta de esto es que no hay manera de dentro de el cuerpo del método que trajeran a la ficha aprobada en (por ejemplo, nada como Task.CurrentTask.CancellationToken
). El token se deberá suministrar a través de algún otro mecanismo, como el objeto de estado o capturado en una lambda.
Entonces, ¿qué propósito tiene que proporciona la cancelación de ficha en el constructor servir?
Solución
La superación de esta ficha en la tarea de constructor se asocia con esta tarea.
la respuesta de Stephen Toub de MSDN :
Esto tiene dos ventajas principales:
- Si el token ha solicitado la cancelación antes de la tarea de comenzar la ejecución, la tarea no se ejecutará. En lugar de la transición a
Running
, que va a pase inmediatamente aCanceled
. Esto evita la gastos de funcionamiento de la tarea si sólo sería cancelado, mientras que en ejecución de todos modos.- Si el cuerpo de la tarea también está supervisando la cancelación de token y lanza una
OperationCanceledException
que contiene esa señal (Que es lo que haceThrowIfCancellationRequested
), a continuación, cuando la tarea ve queOperationCanceledException
, comprueba si coincidencias simbólicas de laOperationCanceledException
del Grupo de simbólico. Si lo hace, esa excepción es vista como un reconocimiento de cancelación cooperativa y las transiciones tarea al Cancelado estado (en lugar del estado de fallo).
Otros consejos
El constructor utiliza el token para el manejo de la cancelación internamente. Si su código quiere acceder al token usted es responsable de pasar a ti mismo. Yo recomendaría la lectura de la href="http://parallelpatterns.codeplex.com/" rel="noreferrer"> Programación Paralela .
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();
La cancelación no es un simple un caso como muchos podrían pensar. Algunas de las sutilezas se explican en esta entrada del blog de MSDN:
Por ejemplo:
En ciertas situaciones en las extensiones paralelas y en otros sistemas, Es necesario despertar un método bloqueado por razones que no se deben a la cancelación explícitamente por un usuario. Por ejemplo, si un hilo es bloqueado en blockingCollection.Take () debido a la colección está vacía y otro subproceso llama posteriormente blockingCollection.CompleteAdding (), entonces la primera llamada debe despertar y lanzar una excepción InvalidOperationException para representar una incorrecta uso.
http://blogs.msdn.com /b/pfxteam/archive/2009/06/22/9791840.aspx