mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +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)
|
||||
{
|
||||
// 优先检查外部取消令牌,若已取消则抛出 OperationCanceledException
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
||||
}
|
||||
|
||||
await timeoutCts.CancelAsync();
|
||||
return await task;
|
||||
await linkedCts.CancelAsync();
|
||||
try
|
||||
{
|
||||
await task;
|
||||
}
|
||||
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested &&
|
||||
timeoutCts.Token.IsCancellationRequested)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -69,13 +78,20 @@ public static class AsyncExtensions
|
||||
|
||||
if (completedTask == delayTask)
|
||||
{
|
||||
// 优先检查外部取消令牌,若已取消则抛出 OperationCanceledException
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
|
||||
}
|
||||
|
||||
await timeoutCts.CancelAsync();
|
||||
await task;
|
||||
await linkedCts.CancelAsync();
|
||||
try
|
||||
{
|
||||
await task;
|
||||
}
|
||||
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested &&
|
||||
timeoutCts.Token.IsCancellationRequested)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -86,6 +102,7 @@ public static class AsyncExtensions
|
||||
/// <param name="maxRetries">最大重试次数</param>
|
||||
/// <param name="delay">重试间隔</param>
|
||||
/// <param name="shouldRetry">判断是否应该重试的函数,默认对所有异常重试</param>
|
||||
/// <param name="throwOriginal">当为 true 时直接抛出原始异常,否则包装为 AggregateException</param>
|
||||
/// <returns>任务结果</returns>
|
||||
/// <exception cref="ArgumentNullException">当 taskFactory 为 null 时抛出</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">当 maxRetries 小于 0 时抛出</exception>
|
||||
@ -99,7 +116,8 @@ public static class AsyncExtensions
|
||||
this Func<Task<T>> taskFactory,
|
||||
int maxRetries,
|
||||
TimeSpan delay,
|
||||
Func<Exception, bool>? shouldRetry = null)
|
||||
Func<Exception, bool>? shouldRetry = null,
|
||||
bool throwOriginal = false)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(taskFactory);
|
||||
|
||||
@ -123,6 +141,9 @@ public static class AsyncExtensions
|
||||
}
|
||||
else
|
||||
{
|
||||
if (throwOriginal)
|
||||
throw;
|
||||
|
||||
throw new AggregateException($"操作在 {attempt} 次重试后仍然失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,10 +23,6 @@ public static class NumericExtensions
|
||||
/// </example>
|
||||
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)
|
||||
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
||||
|
||||
@ -59,10 +55,6 @@ public static class NumericExtensions
|
||||
/// </example>
|
||||
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)
|
||||
throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})");
|
||||
|
||||
@ -109,4 +101,4 @@ public static class NumericExtensions
|
||||
|
||||
return (value - from) / (to - from);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user