首页 > 解决方案 > C#重试方法拦截与免费的AOP框架

问题描述

我对 C# 中的 AOP 完全陌生。目前,我有兴趣为使用此技术的方法编写重试。

所以,基于postsharp tut:https ://doc.postsharp.net/method-interception 我写了这段代码:

[Serializable]
    public class RetryAspect : MethodInterceptionAspect
{
    private int _sleep;
    private int _retries;
    private object _expectedResult;
    private object _defaultReturnValue;

    public RetryAspect(object expectedResult, int waitBetweenCycles, int numberOfRetries) : this(expectedResult, waitBetweenCycles, numberOfRetries, null) { }

    public RetryAspect(object expectedResult, int waitBetweenCycles, int numberOfRetries, object defaultReturnValue)
    {
        _expectedResult = expectedResult;
        _sleep = waitBetweenCycles;
        _retries = numberOfRetries;
        _defaultReturnValue = defaultReturnValue;
    }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        int waitCount = 0;

        while (!args.ReturnValue.Equals(_expectedResult))
        {
            args.Proceed();

            if (waitCount++ < _retries)
            {
                Thread.Sleep(_sleep);
            }
            else
            {
                if (_defaultReturnValue != null)
                {
                    args.ReturnValue = _defaultReturnValue;
                }

                break;
            }
        }
    }
}

class Program
{
    static int cnt = 0;

    static void Main(string[] args)
    {
        Console.WriteLine(Test());
        Console.ReadKey();
    }

    [RetryAspect(true, 1000, 5)]
    public static bool Test()
    {
            Console.WriteLine("Test {0}", cnt);
            if (cnt == 4)
            {
                return true;
            }
            else
            {
                cnt++;
                return false;
            }
    }
}

现在,有没有办法通过使用免费/开源 AOP 框架来实现相同的结果?到目前为止,我没有找到任何具有不同 AOP 框架的有用示例。

标签: c#aop

解决方案


虽然它不是 AOP 我可以建议你使用Polly

Polly 是一个 .NET 弹性和瞬态故障处理库,它允许开发人员表达策略,例如重试......

您只需要使用其流畅的 API 定义您的策略:

var policy = Policy
              .HandleResult<bool>(false)
              //Or using one of WaitAndRetry overloads if you want to sleep between retries 
              .Retry(5);

并执行它:

policy.Execute(() => Test());

推荐阅读