如何在 C# 中编写重试逻辑?

2024 年 8 月 29 日 | 阅读 6 分钟

C# 中的重试逻辑 是一种在放弃或升级失败之前自动重试失败操作多次的技术。它通常用于预期失败是临时或短暂的情况,例如网络超时、数据库连接问题或外部服务故障。理解失败的原因、选择合适的重试策略以及实施有效的错误处理程序对于编写高效的重试逻辑至关重要。

考虑以下情况

您的应用程序正在通过 API 获取数据。突然,由于网络问题,API 暂时中断。如果没有重试逻辑,您的应用程序可能会立即崩溃或进入错误状态。相反,由于实现了重试逻辑,您的应用程序将在一段时间后再次尝试检索数据。如果 API 仍然中断,它可能会稍作等待然后再次尝试,一直重复此循环,直到成功或达到其限制。

在 C# 中,可以通过使用错误处理和循环语句在代码块中更有效地实现此重试逻辑,或者可以通过使用专门为此目的设计的外部库来更有效地处理。这种方法通常用于包含瞬态错误或可能通过更多尝试来解决的问题的过程。

为什么需要重试逻辑?

重试逻辑 是 C# 中用于管理在执行操作时出现的临时问题的编程方法,尤其是在与数据库、Web 服务或 API 等外部资源或服务进行连接时。临时问题,例如网络问题、服务器暂时过载或其他意外因素,都可能导致瞬态错误。 通常会在一段时间后重试该过程以解决这些问题。

  1. 弹性:重试逻辑提高了程序应对临时错误的弹性。如果失败是由于瞬态问题,通过重试该过程可以提高成功的机会。
  2. 改善用户体验:重试逻辑可以通过透明地处理临时错误而无需用户参与来增强用户体验。因此,可以避免服务中断或不必要的错误消息。
  3. 减少外部依赖:许多现代应用程序依赖于外部资源或服务,例如数据库、API 或云服务。使用重试逻辑可以帮助减少可能并不总是可靠的外部依赖的影响。
  4. 降低运营开销:没有重试逻辑,处理临时错误有时需要复杂的错误处理代码或用户干预。重试逻辑通过自动执行重试尝试来简化此过程,从而降低运营开销并管理错误。
  5. 优化资源利用:通过在一段时间内分配重试尝试,重试逻辑可以在失败发生的情况下减少临时资源限制的负担。

重试逻辑的延迟策略

  1. 简单重试:最简单的策略是“简单重试”,即在操作失败时尝试一定次数。
  2. 增量退避:此方法类似于指数退避,在重试之间添加延迟。但是,延迟的增加是线性的,而不是指数级的。如果您仍然希望在重试之间经过一些时间,但又不想经历指数退避偶尔带来的长时间等待,这可能很有用。
  3. 断路器:当多次尝试失败时,此高级方法会“打开”断路器,在特定时间内停止所有进一步的尝试。通过这样做,您可以减少尝试过度负担失败服务的次数。

断路器策略是微服务架构中的一种常见设计模式,它可以防止网络应用程序尝试执行可能反复失败的活动。

以下是其工作原理的简要概述

  1. 闭合状态:最初,断路器处于闭合状态。在这种状态下,可以继续向远程资源或服务发出请求。断路器会监控失败的请求(指定的错误情况或异常)。
  2. 打开状态:当在指定时间段内的失败次数超过特定阈值时,断路器会触发并进入打开状态。在此服务状态下,所有请求将在一段时间内(称为“重置超时”)被自动阻止,并立即返回错误,无需进行网络调用。除了使应用程序免于因反复失败的请求而减慢速度外,它还为失败的服务提供了一些恢复时间。
  3. 半开状态:重置超时结束时,断路器进入半开状态。在此状态下,它允许一定数量的测试请求通过。如果上述请求成功,断路器将返回到闭合状态,并假设服务问题已得到解决。如果测试请求失败,断路器将返回到打开状态,并阻止请求额外的超时期。

使用断路器模式可以增强应用程序的整体稳定性和可用性,它可以帮助使其更加健壮,并防止在尝试可能失败的操作时卡住。

何时实施重试逻辑

  1. 网络操作:在发送网络请求(例如HTTP 请求数据库查询)时,可能会发生超时或拥塞等瞬态问题。重试逻辑(重试失败的请求)可以减轻这些问题。
  2. 文件操作:在读取或写入文件时,可能会出现文件锁定文件系统错误等临时问题。当发生这些错误时,可以使用重试逻辑来重试文件操作。
  3. 数据库操作:超时、锁定冲突或数据库服务器问题可能导致数据库查询或事务暂时失败。通过使用重试逻辑,可以重试失败的数据库操作,直到它们成功。

重试逻辑的组成部分

重试逻辑不仅仅是一个单一的“重试”命令。它是一个由许多相互连接的组件组成的系统,每个组件都对确保逻辑高效有效地运行至关重要。

以下是关键组成部分:

  1. 重试策略:它是一组规则,用于确定何时应重试操作。通常包括最大重试次数和应发生重试的条件。例如,我们可以决定仅在某些异常(如与网络相关的异常)时重试,而避免在其他异常(如与业务逻辑相关的异常)时重试。
  2. 延迟策略:指定重试之间的时间间隔。指数退避延迟方法是一种广泛使用的技术,其中等待时间在每次连续重试时翻倍。建议避免在重试尝试时压垮正在挣扎的系统。
  3. 指数退避:一种更高级的延迟方法,指数退避涉及指数级增加尝试之间的间隔。应该逐渐增加延迟,从小开始,随着每次连续重试而增加,以便为系统提供更多时间来恢复。

常见的变体包括:

  1. 指数增长:每次重试尝试时,延迟都会加倍(即,1 秒、2 秒、4 秒、8 秒,依此类推)。
  2. 随机化指数退避:这种防止同步问题的方法涉及向延迟添加随机因子,这导致重试系统不同实例之间的重试时间出现微小差异。

示例

让我们用一个例子来说明 C# 中的重试逻辑

输出

A simulated transient error occurred.
Attempt 1 is failed: Simulated transient error
Retrying in just 2 seconds...
A simulated transient error occurred.
Attempt 2 is failed: Simulated transient error
Retrying in just 2 seconds...
A simulated transient error occurred.
Attempt 3 is failed: Simulated transient error
Retrying in just 2 seconds...
Simulated successful.

下一主题C# 有趣的事实