Estoy usando una API asíncrona que admite la cancelación y le estoy pasando a esa API una instancia de CancellationToken . Como de costumbre, si se solicita la cancelación en el token pasado, la API que invoco arrojará una OperationCanceledException (este es el patrón de cancelación cooperativo estándar del marco .NET).
Quiero poder capturar OperationCanceledException si y solo si es la excepción generada debido a la cancelación del token de cancelación proporcionado.
El siguiente código ilustra lo que estoy tratando de lograr:
try { await _service.DoSomethingAsync(cancellationToken: token); } catch (OperationCanceledException ex) when ( /* here I want a condition signifying that the OperationCanceledException is caused by the cancellation of the token object */) { // avoid logging the exception: this is raised by design (cooperative cancellation) throw; } catch (Exception ex) { _logger.LogError(ex, "An error occurred: {0}", ex.Message); throw; }Para el filtro de excepción del código anterior, básicamente tengo dos ideas:
IsCancellationRequested en el objeto token : when (token.IsCancellationRequested)CancellationToken en el objeto ex : when (ex.CancellationToken == token)¿Cuál es la forma correcta de hacer la verificación que quiero realizar? ¿Son equivalentes las dos formas mostradas arriba? ¿Existe una mejor práctica?
NOTA IMPORTANTE : sé que el código que se muestra arriba se puede escribir de una manera más eficiente, porque la captura de excepciones es una operación costosa. Probablemente, lo mejor que puede hacer es eliminar el primer bloque catch y solo capturar una Exception si y solo si no está relacionada con la cancelación del objeto token . Soy consciente de eso, pero ese no es el punto de mi pregunta. He escrito el código en la pregunta de esa manera solo para mayor claridad , porque el objetivo de mi pregunta es cómo correlacionar correctamente una OperationCanceledException con CancellationToken que ha causado la excepción en sí.
Quiero poder capturar OperationCanceledException si y solo si es la excepción generada debido a la cancelación del token de cancelación proporcionado.
No puede hacer esto exactamente , pero puede "atrapar la excepción cancelada solo si mi token proporcionado ha sido cancelado", lo que generalmente es lo suficientemente bueno.
when (token.IsCancellationRequested) es lo que desea.
No marque ex.CancellationToken , porque el método al que está llamando puede estar observando un token de cancelación vinculado, que sería diferente al que proporcionó.