单个类,简单好用

using System;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks; namespace Qing
{
public static class QRetry
{
/// <summary>
/// 自定义异常重试
/// </summary>
/// <typeparam name="E"></typeparam>
/// <param name="time"></param>
/// <param name="wait"></param>
/// <param name="action"></param>
/// <param name="retryInfo"></param>
public static void HandException<E>(int time, TimeSpan wait, Action action, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
var task = Task.Run(() =>
{
for (int i = 0; i < (time + 1); i++)
{
try
{
action();
break;
}
catch (E e)
{
if (i == time)
{
break;
}
retryInfo?.Invoke(e, i + 1, wait);
Thread.Sleep(wait);
}
} }); }
/// <summary>
/// 自定义异常重试(有返回,异常返回默认值)
/// </summary>
/// <typeparam name="TResult">返回结果</typeparam>
/// <param name="time">次数</param>
/// <param name="wait">等待时间</param>
/// <param name="action">动作</param>
/// <param name="retryInfo">重试信息</param>
/// <returns></returns>
public static TResult HandException<E, TResult>(int time, TimeSpan wait, Func<TResult> action, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
return Task.Run(() =>
{
TResult result = default(TResult);
for (int i = 0; i < (time + 1); i++)
{
try
{
result = action();
break;
}
catch (E e)
{
if (i == time)
{
break;
}
retryInfo?.Invoke(e, i + 1, wait);
Thread.Sleep(wait);
}
}
return result;
}).Result;
}
/// <summary>
/// 自定义异常重试(有返回,设置异常返回值)
/// </summary>
/// <typeparam name="TResult">返回结果</typeparam>
/// <param name="time">次数</param>
/// <param name="wait">每次等待时间</param>
/// <param name="failedValue">失败返回值</param>
/// <param name="func">执行方法</param>
/// <param name="retryInfo">重试信息(Exception,Time,TimeSpan)</param>
/// <returns></returns>
public static TResult HandException<E, TResult>(int time, TimeSpan wait, TResult failedValue, Func<TResult> func, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
return Task.Run(() =>
{
TResult result = failedValue;
for (int i = 0; i < (time + 1); i++)
{
try
{
result = func();
break;
}
catch (E e)
{
if (i == time)
{
break;
}
retryInfo?.Invoke(e, i + 1, wait);
Thread.Sleep(wait);
}
}
return result;
}).Result;
}
/// <summary>
/// 自定义异常重试
/// </summary>
/// <param name="waits">重试间隔</param>
/// <param name="action">运行方法</param>
/// <param name="retryInfo">重试信息</param>
public static void HandException<E>(TimeSpan[] waits, Action action, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
var task = Task.Run(() =>
{
for (int i = 0; i < (waits.Length + 1); i++)
{
try
{
action();
break;
}
catch (E e)
{
if (i == waits.Length)
{
break;
}
retryInfo?.Invoke(e, i + 1, waits[i]);
Thread.Sleep(waits[i]);
}
} });
}
/// <summary>
/// 自定义异常重试 (有返回,异常返回默认值)
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="waits"></param>
/// <param name="func"></param>
/// <param name="retryInfo"></param>
/// <returns></returns>
public static TResult HandException<E, TResult>(TimeSpan[] waits, Func<TResult> func, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
return Task.Run(() =>
{
TResult result = default(TResult);
for (int i = 0; i < (waits.Length + 1); i++)
{
try
{
result = func();
break;
}
catch (E e)
{
if (i == waits.Length)
{
break;
}
retryInfo?.Invoke(e, i + 1, waits[i]);
Thread.Sleep(waits[i]);
}
}
return result;
}).Result;
} /// <summary>
/// 自定义异常重试 (有返回,设置异常返回值)
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="waits"></param>
/// <param name="func"></param>
/// <param name="retryInfo"></param>
/// <returns></returns>
public static TResult HandException<E, TResult>(TimeSpan[] waits, TResult failedValue, Func<TResult> func, Action<E, int, TimeSpan> retryInfo = null) where E : Exception
{
return Task.Run(() =>
{
TResult result = failedValue;
for (int i = 0; i < (waits.Length + 1); i++)
{
try
{
result = func();
break;
}
catch (E e)
{
if (i == waits.Length)
{
break;
}
retryInfo?.Invoke(e, i + 1, waits[i]);
Thread.Sleep(waits[i]);
}
}
return result;
}).Result;
} /// <summary>
/// 结果判断重试(异常也重试)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <param name="time"></param>
/// <param name="wait"></param>
/// <param name="func"></param>
/// <param name="retryInfo"></param>
/// <returns></returns>
public static T HandResult<T>(Expression<Func<T, bool>> expression, int time, TimeSpan wait, Func<T> func, Action<string, int, TimeSpan> retryInfo = null)
{
var exp = expression.Compile();
return Task.Run(() =>
{
var result = default(T);
for (int i = 0; i < (time + 1); i++)
{
try
{
result = func();
if (i == time)
{
break;
}
else if (exp.Invoke(result))
{
retryInfo?.Invoke("结果命中约束条件", i + 1, wait);
Thread.Sleep(wait);
continue;
}
else
{
break;
}
}
catch (Exception e)
{
if (i == time)
{
break;
}
retryInfo?.Invoke(e.Message, i + 1, wait);
Thread.Sleep(wait);
}
}
return result;
}).Result; } /// <summary>
/// 结果判断重试(异常也重试)
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="expression">判断表达式</param>
/// <param name="waits">每次重试间隔</param>
/// <param name="func">执行方法</param>
/// <param name="retryInfo">重试信息</param>
/// <returns></returns>
public static T HandResult<T>(Expression<Func<T, bool>> expression, TimeSpan[] waits, Func<T> func, Action<string, int, TimeSpan> retryInfo = null)
{
var exp = expression.Compile();
return Task.Run(() =>
{
var result = default(T);
for (int i = 0; i < (waits.Length + 1); i++)
{
try
{
result = func();
if (i == waits.Length)
{ break;
}
else if (exp.Invoke(result))
{
retryInfo?.Invoke("结果命中约束条件", i + 1, waits[i]);
Thread.Sleep(waits[i]);
continue;
}
else
{
break;
}
}
catch (Exception e)
{
if (i == waits.Length)
{
break;
}
retryInfo?.Invoke(e.Message, i + 1, waits[i]);
Thread.Sleep(waits[i]);
}
}
return result;
}).Result;
}
} }

  

调用示例:

//调用门店开通方法,依据结果判断Result!="OK",那么过 20秒再重试,一共重试20次
var createResult = Qing.QRetry.HandResult<CreateStoreResult>(x => x.result != "OK", 20, TimeSpan.FromSeconds(20), () =>
{
//开店动作
return StoreManager.Instance.CreateStore(storeArg); }, (msg, count, ts) =>
{
Qing.QLog.SendLog_Debug($"{storeName}开通执行异常:{msg};{ts.TotalSeconds}s 后进行第{count}次重试。");
}
);

 

方法命名上参考了Polly。正经项目还是用Polly好。

一个简单的异常/条件重试类(C#)的更多相关文章

  1. 实现一个简单的http请求工具类

    OC自带的http请求用起来不直观,asihttprequest库又太大了,依赖也多,下面实现一个简单的http请求工具类 四个文件源码大致如下,还有优化空间 MYHttpRequest.h(类定义, ...

  2. Qt5.9一个简单的多线程实例(类QThread)(第一种方法)

    Qt开启多线程,主要用到类QThread.有两种方法,第一种用一个类继承QThread,然后重新改写虚函数run().当要开启新线程时,只需要实例该类,然后调用函数start(),就可以开启一条多线程 ...

  3. 一个简单小巧的CSV读取类

    最近在基于亚马逊MWS API做一些服务,需要读取亚马逊返回的报表,是一个按照\t分割的文本,所以就封装了一个简单小巧的CsvReader类 使用方法 使用方法非常简单,只需要传递一个stream子类 ...

  4. Java下一个简单的数据库分库帮助类

    简介    前面两篇文章主要讲了数据库读写分离和分表分库的一些问题,这篇文章主要讲一下我个人实现的一个分表分库项目.     在此之前,我有写过一个.Net的分库,最近在做Java的项目,就顺便做出一 ...

  5. 一个简单IP防刷工具类, x秒内最多允许y次单ip操作

    IP防刷,也就是在短时间内有大量相同ip的请求,可能是恶意的,也可能是超出业务范围的.总之,我们需要杜绝短时间内大量请求的问题,怎么处理? 其实这个问题,真的是太常见和太简单了,但是真正来做的时候,可 ...

  6. 一个简单清晰的Redis操作类

    <?php /** * redis处理的二次封装 * */ class Redis{ private $_redis; private $_config; public function __c ...

  7. 一个简单清晰的Redis操作类-php

    <?php /** * redis处理的二次封装 * */ class Redis{ private $_redis; private $_config; public function __c ...

  8. 分享给大家一个简单的数据导出excel类

    <?php /** * 生成excel文件操作 * * @author wesley wu * @date 2013.12.9 */ class Excel { private $limit = ...

  9. 一个简单的Java文件工具类

    package com.xyworkroom.ntko.util; import java.io.File; import java.io.FileInputStream; import java.i ...

随机推荐

  1. UNIX 基础知识

    登陆       1.登录名            系统在其 口令文件(通常是/etc/passwd文件) 中查看用户名,口令文件中包含了有关用户的信息.       2.shell          ...

  2. MySQL存储引擎(engine:处理表的处理器)

    1.基本的操作命令: 1.查看所有存储引擎 show engines: 2.查看已有表的存储引擎: show create table 表名: 3.创建表指定的存储引擎 create table 表名 ...

  3. Android:数据持久化(1/2)文件、SharedPreferences

    Summary 持久化的3种方法: 普通文件:I/O流操作文件: SharedPreferences:XML文件,通过key-value pair的形式存储数据: SQLite:Android自带数据 ...

  4. ios 视图切换翻页效果

    本文写的是视图切换,涉及到的内容有 1.实现代码添加Navigation Bar  Toolbal: 2.实现在Navigation Bar和Toolbar上用代码添加Bar Button Item: ...

  5. Python学习-字典练习:简单通讯录

    功能要求: 查询联系人,输入姓名,可以查询当前通讯录里面的联系人信息,若联系人存在,则输出联系人信息,若不存在,则告知 插入联系人,可以向通讯录中新建联系人,若联系人已经存在,则询问是否修改联系人信息 ...

  6. ballerina 学习十三 函数&&documentation

    ballerina 函数和其他语言一样的,可以实现重用 简单例子 代码 import ballerina/io; documentation { `User` is a user defined ob ...

  7. IDEA使用介绍

    https://blog.csdn.net/qq_27093465/article/details/77449117

  8. [LeetCode系列]括号生成问题

    给定n, 返回所有匹配的n对括号的可能形式. 如 给定 n = 3, 一个解集是: "((()))", "(()())", "(())()" ...

  9. hadoop之 HDFS-Hadoop存档

    每个文件按块方式存储, 每个块的元数据存储在namenode的内存中 Hadoop存档文件或HAR文件是一个更高效的文件存档工具,它将文件存入HDFS块,在减少内存使用的同时,允许对文件进行透明地访问 ...

  10. yum安装postgresql

    https://wiki.postgresql.org/wiki/YUM_Installation