namespace GFramework.Core.extensions;
///
/// 异步扩展方法
///
public static class AsyncExtensions
{
///
/// 为任务添加超时限制
///
/// 任务结果类型
/// 接收取消令牌并返回任务的工厂方法,令牌将在超时或外部取消时触发
/// 超时时间
/// 外部取消令牌
/// 任务结果
/// 当 taskFactory 为 null 时抛出
/// 当任务超时时抛出
/// 当操作被取消时抛出
///
///
/// var result = await WithTimeout(
/// ct => SomeAsyncOperation(ct),
/// TimeSpan.FromSeconds(5));
///
///
public static async Task WithTimeout(
Func> taskFactory,
TimeSpan timeout,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(taskFactory);
// linkedCts 同时响应:超时 + 外部取消
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
linkedCts.CancelAfter(timeout);
Task task;
try
{
// 将联合令牌传入实际任务,超时时任务会收到取消信号
task = taskFactory(linkedCts.Token);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
}
try
{
return await task.ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested
&& linkedCts.IsCancellationRequested)
{
// linkedCts 触发但外部未取消 → 超时
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
}
}
///
/// 为任务添加超时限制(无返回值版本)
///
/// 接收取消令牌并返回任务的工厂方法
/// 超时时间
/// 外部取消令牌
/// 当 taskFactory 为 null 时抛出
/// 当任务超时时抛出
/// 当操作被取消时抛出
public static async Task WithTimeout(
Func taskFactory,
TimeSpan timeout,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(taskFactory);
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
linkedCts.CancelAfter(timeout);
Task task;
try
{
task = taskFactory(linkedCts.Token);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
}
try
{
await task.ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested
&& linkedCts.IsCancellationRequested)
{
throw new TimeoutException($"操作在 {timeout.TotalSeconds} 秒后超时");
}
}
///
/// 为任务添加失败回退机制
///
/// 任务结果类型
/// 要执行的任务
/// 失败时的回退函数
/// 任务结果或回退值
/// 当 task 或 fallback 为 null 时抛出
///
///
/// var result = await RiskyOperation()
/// .WithFallback(ex => DefaultValue);
///
///
public static async Task WithFallback(this Task task, Func fallback)
{
ArgumentNullException.ThrowIfNull(task);
ArgumentNullException.ThrowIfNull(fallback);
try
{
return await task;
}
catch (Exception ex)
{
return fallback(ex);
}
}
}