如何为RestSharp的GET/POST请求实现连接失败(StatusCode 0)重试机制?
RestSharp连接失败(StatusCode=0)的重试优化方案
直接在每个接口方法里加for循环太冗余,维护成本高,还会让重试逻辑和业务代码耦合,不符合单一职责原则。下面给两个更合理的实现方式:
1. 封装通用重试工具方法
写一个可复用的重试函数,把接口调用逻辑作为委托传进去,仅当返回StatusCode=0时触发重试。所有接口调用都能共用这个逻辑,不用重复写循环。
示例代码
先实现通用重试方法:
/// <summary> /// 仅针对RestSharp连接失败(StatusCode=0)的通用重试方法 /// </summary> /// <param name="requestAction">要执行的RestSharp请求逻辑</param> /// <param name="maxRetries">最大重试次数,默认3次</param> /// <returns>最终的RestResponse结果</returns> public static RestResponse ExecuteWithConnectionRetry(Func<RestResponse> requestAction, int maxRetries = 3) { int retryAttempt = 0; while (true) { var response = requestAction.Invoke(); // 非连接失败,直接返回结果 if (response.StatusCode != 0) { return response; } retryAttempt++; if (retryAttempt > maxRetries) { Logger.Error($"连接失败重试次数耗尽(共{maxRetries}次),终止重试"); return response; } Logger.Info($"连接失败,进行第{retryAttempt}次重试..."); // 指数退避延迟,避免频繁请求加重服务端负担 Thread.Sleep(1000 * retryAttempt); } }
改造业务方法,让它们返回原始RestResponse(方便统一判断状态码):
public RestResponse Login() { var client = new RestClient("你的API基础地址"); var request = new RestRequest("/login", Method.Post); // 填充登录参数 return client.Execute(request); } public RestResponse GetItemsInventory() { var client = new RestClient("你的API基础地址"); var request = new RestRequest("/inventory", Method.Get); return client.Execute(request); } public RestResponse PostItemsInventory(ItemsSold itemsSold) { var client = new RestClient("你的API基础地址"); var request = new RestRequest("/inventory", Method.Post); request.AddJsonBody(itemsSold); return client.Execute(request); }
在Main方法中调用:
static void Main(string[] args) { // 登录重试 var loginResp = ExecuteWithConnectionRetry(() => Login()); if (loginResp.StatusCode != HttpStatusCode.OK) { Logger.Error("登录失败(非连接问题)"); return; } // 获取库存重试 var inventoryResp = ExecuteWithConnectionRetry(() => GetItemsInventory()); if (inventoryResp.StatusCode == HttpStatusCode.BadRequest) { Logger.Error("库存请求数据错误"); return; } if (inventoryResp.StatusCode == HttpStatusCode.Created) { Logger.Info("库存数据获取成功"); var items = JsonConvert.DeserializeObject<Items>(inventoryResp.Content); // 处理库存数据 } // 提交库存重试 var postResp = ExecuteWithConnectionRetry(() => PostItemsInventory(ItemsSold)); if (postResp.StatusCode == HttpStatusCode.Created) { Logger.Info("库存数据提交成功"); // 后续处理 } }
2. 利用RestSharp内置重试(107+版本适用)
如果你的项目使用RestSharp 107及以上版本,可以直接用框架自带的重试策略,通过配置RestClient指定仅针对StatusCode=0的情况重试,代码更简洁。
示例代码
// 配置RestClient的重试策略 var clientOptions = new RestClientOptions("你的API基础地址") { MaxTimeout = 10000, RetryPolicy = new RetryPolicy( retryCount: 3, // 仅当StatusCode=0时触发重试 retryCondition: resp => resp.StatusCode == 0, // 重试延迟:第1次等1秒,第2次等2秒,以此类推 delayProvider: retryNum => TimeSpan.FromSeconds(retryNum) ) }; var client = new RestClient(clientOptions);
业务方法直接使用配置好的client,框架会自动处理重试:
public RestResponse Login(RestClient client) { var request = new RestRequest("/login", Method.Post); // 填充参数 return client.Execute(request); }
方案选择
- 若使用RestSharp 107+,优先选内置重试,代码更简洁,符合框架设计。
- 版本较低或需要自定义重试逻辑(比如结合异常处理),则用通用重试方法,灵活性更高。
内容的提问来源于stack exchange,提问作者ISeeMangos
相关产品推荐
相关产品推荐

