c# - cancellationtoken - ¿Debo usar IsCancellationRequested de token o source cuando ambos estén disponibles?
cancellationtoken iscancellationrequested (3)
Si tengo un CancellationTokenSource que todavía está en el alcance cuando estoy buscando la cancelación, por ejemplo, si acabo de realizar una consulta en la base de datos y aún no he pasado el Cancelación Retirada a Tareas para procesar los resultados, ¿debo acceder a IsCancellationRequested? desde la fuente o desde su token?
En otras palabras, si ambas opciones están disponibles, ¿cuál es la preferida y por qué?
1:
myCancellationTokenSource.IsCancellationRequested
2:
myCancellationTokenSource.Token.IsCancellationRequested
En este escenario particular, creo que los dos son esencialmente equivalentes. Preferiría usar el Token solo porque esto simplifica la refactorización si luego se divide la cancelación de verificación lógica de la lógica que crea la fuente de cancelación. Para promover ese fin, almacenaría el token en una referencia local y usaría esa referencia para la verificación.
Normalmente, myCancellationTokenSource
se utiliza para iniciar la cancelación (por un hilo padre, por ejemplo). myCancellationTokenSource.Token
es el CancellationToken
asociado que pasaría a algo como TaskFactory.StartNew()
. La tarea entonces supervisaría el CancellationToken.IsCancellationRequested
para determinar cuándo cerrar.
Usaría un token, aunque al menos para la variante 1, el efecto probablemente sea el mismo. Los CancellationTokens son tipos de valor de solo lectura que deben pasar alrededor del código del cliente mientras que el CancellationTokenSource es un IDisposable con algunos recursos internos ... Por razones de seguridad, prefiero usarlo así:
void MethodA() {
// Context in which CancellationTokenSource is known
using (var tSource = new CancellationTokenSource()) {
ThreadPool.QueueWorkItem( pArg => MethodB(tSource.Token) );
ThreadPool.QueueWorkItem( pArg => MethodC(tSource.Token) );
// ...
// some other work to do
// cancel
if (mSomethingHappend) {
tSource.Cancel();
}
}
}
private static void MethodB( CancellationToken pToken )
{
// ...
}