mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 13:33:28 +08:00
fix(async): 修复异步扩展中的超时和重试逻辑问题
- 修复TimeoutAfter方法中的取消令牌处理逻辑,避免OperationCanceledException被意外捕获 - 修复RetryAsync方法中的参数验证,移除对可空值类型的空值检查 - 为RetryAsync方法添加throwOriginal参数以控制异常抛出行为 - 统一超时处理中的令牌取消方式,使用linkedCts.Cancel()替代timeoutCts.CancelAsync()
This commit is contained in:
parent
475f301d9f
commit
850fecdff4
@ -36,13 +36,22 @@ public static class AsyncExtensions
|
|||||||
|
|
||||||
if (completedTask == delayTask)
|
if (completedTask == delayTask)
|
||||||
{
|
{
|
||||||
// 优先检查外部取消令牌,若已取消则抛出 OperationCanceledException
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
||||||
}
|
}
|
||||||
|
|
||||||
await timeoutCts.CancelAsync();
|
await linkedCts.CancelAsync();
|
||||||
return await task;
|
try
|
||||||
|
{
|
||||||
|
await task;
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested &&
|
||||||
|
timeoutCts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return task.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -69,13 +78,20 @@ public static class AsyncExtensions
|
|||||||
|
|
||||||
if (completedTask == delayTask)
|
if (completedTask == delayTask)
|
||||||
{
|
{
|
||||||
// 优先检查外部取消令牌,若已取消则抛出 OperationCanceledException
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
||||||
}
|
}
|
||||||
|
|
||||||
await timeoutCts.CancelAsync();
|
await linkedCts.CancelAsync();
|
||||||
await task;
|
try
|
||||||
|
{
|
||||||
|
await task;
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested &&
|
||||||
|
timeoutCts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -86,6 +102,7 @@ public static class AsyncExtensions
|
|||||||
/// <param name="maxRetries">最大重试次数</param>
|
/// <param name="maxRetries">最大重试次数</param>
|
||||||
/// <param name="delay">重试间隔</param>
|
/// <param name="delay">重试间隔</param>
|
||||||
/// <param name="shouldRetry">判断是否应该重试的函数,默认对所有异常重试</param>
|
/// <param name="shouldRetry">判断是否应该重试的函数,默认对所有异常重试</param>
|
||||||
|
/// <param name="throwOriginal">当为 true 时直接抛出原始异常,否则包装为 AggregateException</param>
|
||||||
/// <returns>任务结果</returns>
|
/// <returns>任务结果</returns>
|
||||||
/// <exception cref="ArgumentNullException">当 taskFactory 为 null 时抛出</exception>
|
/// <exception cref="ArgumentNullException">当 taskFactory 为 null 时抛出</exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">当 maxRetries 小于 0 时抛出</exception>
|
/// <exception cref="ArgumentOutOfRangeException">当 maxRetries 小于 0 时抛出</exception>
|
||||||
@ -99,7 +116,8 @@ public static class AsyncExtensions
|
|||||||
this Func<Task<T>> taskFactory,
|
this Func<Task<T>> taskFactory,
|
||||||
int maxRetries,
|
int maxRetries,
|
||||||
TimeSpan delay,
|
TimeSpan delay,
|
||||||
Func<Exception, bool>? shouldRetry = null)
|
Func<Exception, bool>? shouldRetry = null,
|
||||||
|
bool throwOriginal = false)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(taskFactory);
|
ArgumentNullException.ThrowIfNull(taskFactory);
|
||||||
|
|
||||||
@ -123,6 +141,9 @@ public static class AsyncExtensions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (throwOriginal)
|
||||||
|
throw;
|
||||||
|
|
||||||
throw new AggregateException($"操作在 {attempt} 次重试后仍然失败", ex);
|
throw new AggregateException($"操作在 {attempt} 次重试后仍然失败", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,10 +23,6 @@ public static class NumericExtensions
|
|||||||
/// </example>
|
/// </example>
|
||||||
public static T Clamp<T>(this T value, T min, T max) where T : IComparable<T>
|
public static T Clamp<T>(this T value, T min, T max) where T : IComparable<T>
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(value);
|
|
||||||
ArgumentNullException.ThrowIfNull(min);
|
|
||||||
ArgumentNullException.ThrowIfNull(max);
|
|
||||||
|
|
||||||
if (min.CompareTo(max) > 0)
|
if (min.CompareTo(max) > 0)
|
||||||
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
||||||
|
|
||||||
@ -59,10 +55,6 @@ public static class NumericExtensions
|
|||||||
/// </example>
|
/// </example>
|
||||||
public static bool Between<T>(this T value, T min, T max, bool inclusive = true) where T : IComparable<T>
|
public static bool Between<T>(this T value, T min, T max, bool inclusive = true) where T : IComparable<T>
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(value);
|
|
||||||
ArgumentNullException.ThrowIfNull(min);
|
|
||||||
ArgumentNullException.ThrowIfNull(max);
|
|
||||||
|
|
||||||
if (min.CompareTo(max) > 0)
|
if (min.CompareTo(max) > 0)
|
||||||
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user