代码改变世界

c# .Net重试机制

2021-05-12 17:29  石吴玉  阅读(1444)  评论(0编辑  收藏  举报

问题描述:某些场景下,需要对产生异常的任务或没有达到预期结果的任务进行重试,若重试次数达到了我们设定的阈值,则再放弃任务

简单方法:

public static void Operat(int count = 3)
{
    //循环重试次数
    for (int i = 0; i < count; i++)
    {
        try
        {
            //执行目标方法,若无异常,则结束循环,返回
            SomeFunctionThatCanFail();
            break;
        }
        catch (Exception ex)
        {
            //若发生了异常,则打印日志,休眠5秒钟之后继续重试
            Console.WriteLine($"异常!{i}");
            Thread.Sleep(5000);
        }
    }
}

 

方案一

使用一个静态的泛型方法来处理,创建通用的任务重试机制,我们可以使用action作为参数,如下:

public class Program
    {
        static void Main(string[] args)
        {
            DoAction<bool>(()=>SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1), 2);
            Console.Read();
        }

        public static bool SomeFunctionThatCanFail()
        {
            Console.WriteLine("方法");
            Convert.ToInt32("nihao");
            return false;
        }

        public static void DoAction<T>(Func<T> action, TimeSpan retryInterval, int maxAttempCount = 3)
        {
            var exceptions = new List<Exception>();
            for (int i = 0; i < maxAttempCount; i++)
            {
                try
                {
                    var result = action();

                    if (i > 0)
                        Thread.Sleep(i);
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }
            }
        }
    }
View Code

 

方案二

使用第三方组件,eg:Polly,Polly是一个任务重试解决方案组件,用Polly你可以非常方便地完成如:Retry,Retry Forever,Wait and Retry或者Circuit Breaker等等重试操作,并且Polly的重试写法是链式的,如:

 

 方案三

以下方法可以在重试失败时补充异常处理方法

public class Program
    {
        static void Main(string[] args)
        {
            DoAction(()=> SomeFunctionThatCanFail(), ()=> Log(),3);
            Console.Read();
        }

        public static bool SomeFunctionThatCanFail()
        {
            Console.WriteLine("进入任务内容");
            Convert.ToInt32("nihao");
            return false;
        }

        public static void Log()
        {
            Console.WriteLine("产生异常!");
        }

        public static void DoAction<T>(Func<T> action,Action OnFailureAction, int maxAttempCount = 3)
        {
            var exceptions = new List<Exception>();
            for (int i = 0; i < maxAttempCount; i++)
            {
                try
                {
                    var result = action();

                    if (i > 0)
                        Thread.Sleep(i);
                }
                catch (Exception ex)
                {
                    OnFailureAction();
                }
            }
        }
    }
View Code