C# 为异步函数实现WaitAsync方法

C# 为异步函数实现WaitAsync方法

​.NET 6 开始,System.Threading.Tasks.Task类 ​原生提供了 WaitAsync方法,该方法可以很方便的为任意异步函数提供超时功能。但是Framework没有该方法。不过我们可以通过Task.WhenAny方法可以实现类似的功能 。

  1. 无返回值
csharp 复制代码
/// <summary>
/// 异步等待任务完成,支持超时
/// </summary>
/// <param name="task">要等待的任务</param>
/// <param name="timeoutMilliseconds">超时时间(毫秒)</param>
/// <returns>任务本身</returns>       
public static async Task WaitAsync(this Task task, int timeout)
{
    if (task == null)
        throw new ArgumentNullException(nameof(task));
    if (task.IsCompleted)
        return;
    using (CancellationTokenSource cts = new CancellationTokenSource())
    {
        Task completedTask = await Task.WhenAny(task, Task.Delay(timeout, cts.Token)).ConfigureAwait(false);
        if (completedTask != task)
            throw new TimeoutException($"等待任务超时({timeout} 毫秒)");
        cts.Cancel();
        await task.ConfigureAwait(false);
    }
}
  1. 有返回值
csharp 复制代码
/// <summary>
/// 异步等待一个 Task<T> 完成,并获取结果,支持超时
/// </summary>
/// <typeparam name="T">任务返回的数据类型</typeparam>
/// <param name="task">要等待的任务</param>
/// <param name="timeoutMilliseconds">超时时间(毫秒)</param>
/// <returns>任务的结果 T</returns>      
public static async Task<T> WaitAsync<T>(this Task<T> task, int timeout)
{
    if (task == null)
        throw new ArgumentNullException(nameof(task));
    if (task.IsCompleted)
        return task.Result;
    using (CancellationTokenSource cts = new CancellationTokenSource())
    {
        Task completedTask = await Task.WhenAny(task, Task.Delay(timeout, cts.Token)).ConfigureAwait(false);
        if (completedTask != task)
            throw new TimeoutException($"等待任务超时({timeout} 毫秒)");
        cts.Cancel();
        return await task.ConfigureAwait(false);
    }
}
相关推荐
志尊宝13 小时前
Vue3 零基础每日笔记(048):嵌套路由与命名视图——后台管理系统布局雏形
前端·javascript·vue.js·笔记·html5
Mr.Meng_9513 小时前
彻底搞懂Promise.allSettled:用法、场景、源码手写、面试题详解
前端
此时不提桶,更待何时14 小时前
02-05-B-虚拟线程面试与生产事故实战
java·面试
名字还没想好☜14 小时前
Spring Boot 3.2 RestClient 实战:替代 RestTemplate 调外部接口,超时、连接池与错误处理
java·后端·spring
心易行者14 小时前
Python在线运行+SQLite数据库实战:0成本搭个人数据后台,5个场景直接套用
前端·网络·人工智能·python
@tangguo12314 小时前
npm 和 yarn 配置说明
前端·javascript·npm·node.js·yarn
摇滚侠14 小时前
《Spring Boot 3:高级与架构设计》第 2 章 IOC容器的高级机制 BeanFactoryPostProcessor 个人理解 6
java·spring boot·笔记·后端
zhiyouTech14 小时前
GEO实战:把生成式引擎优化当成检索工程来做(含五断点诊断与50题Benchmark)
前端·人工智能
志尊宝14 小时前
Vue3 零基础每日笔记(052):路由常见坑一次排雷——404、刷新丢参数、部署白屏
前端·javascript·vue.js·笔记·html5
linux_cfan14 小时前
videojs v10 源代码系列解读:13 · 能力型媒体契约:`Media` 的组合接口
前端·javascript·音视频