namespace GFramework.Core.extensions; /// /// 异步扩展方法 /// public static class AsyncExtensions { /// /// 为任务添加超时限制 /// /// 任务结果类型 /// 接收取消令牌并返回任务的工厂方法,令牌将在超时或外部取消时触发 /// 超时时间 /// 外部取消令牌 /// 任务结果 /// 当 taskFactory 为 null 时抛出 /// 当任务超时时抛出 /// 当操作被取消时抛出 /// /// /// var result = await WithTimeoutAsync( /// ct => SomeAsyncOperation(ct), /// TimeSpan.FromSeconds(5)); /// /// public static async Task WithTimeoutAsync( 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 WithTimeoutAsync( 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() /// .WithFallbackAsync(ex => DefaultValue); /// /// public static async Task WithFallbackAsync(this Task task, Func fallback) { ArgumentNullException.ThrowIfNull(task); ArgumentNullException.ThrowIfNull(fallback); try { return await task; } catch (Exception ex) { return fallback(ex); } } }