es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Detener la ejecución en ciertas condiciones en Polly 4.3

Comenzamos a utilizar la biblioteca Polly en nuestro antiguo proyecto WinForms que aún se ejecuta en el marco de trabajo .NET 4.0 (es un requisito).

El problema es que tenemos que utilizar la versión 4.3 de la biblioteca Polly y nos resulta difícil encontrar soluciones a los problemas porque toda la documentación que encontramos se refiere a versiones más recientes de la biblioteca.

Por ejemplo, no podemos pasar valores de Context desde la devolución de llamada de reintentos a Execute porque Context es de solo lectura y no podemos pasar parámetros al delegado Execute porque utiliza un tipo Action.

Para todos estos problemas hemos encontrado una solución creativa, pero aún no hemos encontrado una forma de detener la ejecución en ciertas condiciones.

En Polly 5, se introdujo CancellationToken con este propósito, pero supongo que también había formas de forzar el reintento a detenerse en versiones anteriores.

public RetryPolicy DevicePolicy => Policy
.Handle()
.WaitAndRetry(
MaxRetries,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, retryCount, context) =>
{
//Si obtengo la excepción de tiempo de espera, quiero detener la ejecución
if (exception is TimeoutException)
{
//En Polly 5.0 puedo establecer el cancellationToken pero con 4.3 no existe
var cts = context[“CancellationTokenSource”] as CancellationTokenSource;
cts.Cancel();
}
else
{
var errHeader = $”error de conexión del dispositivo. Intento {retryCount} de {MaxRetries}”;
Log.Warn(errHeader, exception);
}
});

¿Algún idea?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una posible solución podría ser usar un CancellationTokenSource compartido en su proyecto de WinForms, que se puede pasar a la política de reintento como un valor de contexto. Luego, puede verificar la propiedad IsCancellationRequested del CancellationToken en su delegado de ejecución para determinar si la ejecución debe detenerse.

    Aquí hay una implementación de ejemplo:

    // Inicialice un CancellationTokenSource compartido
    var cancellationTokenSource = new CancellationTokenSource();
    
    // Pase el CancellationTokenSource como un valor de contexto a la política de reintento
    var policy = Policy
        .Handle<exception>()
        .WaitAndRetry(
            maxRetryCount: 3,
            sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
            onRetry: (exception, retryCount, context) =>
            {
                if (exception is TimeoutException)
                {
                    Log.Warn("La ejecución se ha cancelado debido a una excepción de tiempo de espera.");
                    cancellationTokenSource.Cancel();
                }
                else
                {
                    Log.Warn($"El intento de reintento {retryCount} falló con la excepción {exception}.");
                }
            })
        .WithCancellation(cancellationTokenSource.Token);
    
    // Pase el CancellationToken al delegado de ejecución
    try
    {
        await policy.ExecuteAsync(async cancellationToken =>
        {
            // Verifique si se ha solicitado la cancelación
            cancellationToken.ThrowIfCancellationRequested();
    
            // Ejecute su código aquí
            await MyLegacyMethodAsync();
    
        }, cancellationTokenSource.Token);
    }
    catch (OperationCanceledException)
    {
        Log.Warn("La ejecución se ha cancelado.");
    }
    

    Esta implementación utiliza una función anónima para pasar tanto el CancellationToken como el CancellationTokenSource al delegado de ejecución. Dentro del delegado, puede verificar si se ha solicitado la cancelación antes de ejecutar su código heredado. Si se solicita la cancelación, se lanzará una OperationCanceledException, que se puede capturar para manejar la cancelación.

    Tenga en cuenta que el método Policy.WithCancellation se introdujo en Polly 5.0, pero aún puede usarlo con Polly 4.3 instalando el paquete NuGet Microsoft.Bcl.AsyncInterfaces.

Comments are closed.