Cualquier forma de diferenciar Cancelar y Tiempo de espera

Tengo un código que valida algunos datos al hacer llamadas a otros servicios. Comienzo todas las llamadas en paralelo y luego espero hasta que al menos una de ellas finalice. Si alguna de las solicitudes falla, no me importa el resultado de las otras llamadas.

Hago las llamadas conHttpClient y he pasado unHttpMessageHandler en eso hace un montón de registro. Esencialmente:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    HttpResponseMessage response = null;

    try
    {
        response = await base.SendAsync(request, cancellationToken);
    }
    catch (OperationCanceledException ex)
    {
        LogTimeout(...);
        throw;
    }
    catch (Exception ex)
    {
        LogFailure(...);
        throw;
    }
    finally
    {
        LogComplete(...);
    }

    return response;
}

No, la parte con la que tengo problemas es cuando cancelo las solicitudes. Cuando cancelo una solicitud, lo hago a propósito, por lo que no quiero que se registre como un tiempo de espera, pero no parece haber ninguna diferencia entre una cancelación y un tiempo de espera real.

¿Hay alguna forma de lograr esto?

Editar: Necesito aclarar esto, un poco. El servicio que realiza las llamadas en paralelo pasa en CancellationTokens con un tiempo de espera:

var ct = new CancellationTokenSource(TimeSpan.FromSeconds(2));

Entonces, cuando el servidor tarda más de dos segundos en responder, recibo unOperationCanceledException, y si cancelo manualmente el origen del token (por ejemplo, porque otro servidor devolvió un error después de 1 segundo), sigo obteniendo unOperationCanceledException. Idealmente, podría mirarCancellationToken.IsCancellationRequested para determinar si se canceló debido a un tiempo de espera, en lugar de solicitarlo explícitamente, pero parece que obtiene el mismo valor independientemente decómo fue cancelado.

Respuestas a la pregunta(2)

Su respuesta a la pregunta