LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

使用 C# ValueTask,进一步提升你的异步代码性能

admin
2025年6月25日 22:7 本文热度 30

前言

嗨,程序员小伙伴们,早上好!

今天我们要聊一个能让你的异步代码既快又省的小能手——ValueTask。

如果你还在只用Task写异步代码,那就像开跑车却一直挂一档,太浪费啦!

微软在.NET Core 2.1中悄悄引入了一个性能小怪兽——ValueTask。

它就像Task的轻量级表弟,虽然个头小,但在某些场合下能发挥惊人的威力!

记得我第一次用 ValueTask 优化代码时,那个性能提升简直让我怀疑自己的眼睛。

什么是 ValueTask?

简单来说,ValueTask<T> 是一种结构体(struct),而 Task<T> 则是一个类(class)。

这意味着 ValueTask<T> 可以避免一些不必要的对象分配,从而减少垃圾回收的压力,特别是在高性能要求的场景下尤为重要。

ValueTask vs Task

现在我们来看看 ValueTask 和 Task 的区别:

Task 就像你家的SUV——功能全面但油耗高,每次异步操作都需要在堆(heap)上分配新对象。

ValueTask 则像是一辆混合动力小车——当操作能同步完成时,它直接利用栈(stack)上的值类型,完全避免堆分配!

所以这也是我们选择 ValueTask 的理由:

  • ValueTask 允许你返回一个已经完成的结果,而不需要创建新的 Task 对象,可以减少内存分配

  • 由于减少了临时对象的创建,使用 ValueTask 可以显著降低垃圾回收器的工作负担

代码对比

// 传统Task方式
public async Task<intGetDataAsync()
{
    // 总会产生堆分配
    await Task.Delay(100);
    return42;
}

// ValueTask方式
public async ValueTask<intGetDataOptimizedAsync()
{
    // 检查数据是否已经缓存
    // 如果是,则直接返回,无堆分配!
    // 这里随便返回一个值,实际中,这里是返回缓存中的键值
    if (isDataCached) return42

    await Task.Delay(100);
    return42;
}

在上面这个例子中,我们可以看到,当结果可以同步获取时,ValueTask 可以避免不必要的堆分配,从而提高性能

什么时候该用ValueTask?

记住这个黄金法则:当你的方法经常(>50%)能同步完成时,用ValueTask

比如:

  • 缓存命中的情况
  • 对象池实现
  • 高频调用的简单异步操作
  • 性能敏感的库代码

总结

无论是为了提高应用的响应速度,还是减少不必要的内存开销,合理地使用 ValueTask 都能让我们的程序运行得更加流畅。

不过要注意的是,不要多次 await 同一个 ValueTask,这会带来灾难性的后果,比如:

ValueTask<int> vt = GetDataOptimizedAsync();
int result1 = await vt; // 第一次 await 没问题
int result2 = await vt; // 这里会抛出异常

如果需要多次使用,先转换为Task,如:

Task<int> task = vt.AsTask();
int result1 = await task;
int result2 = await task; // 现在安全了

好了,今天的分享就到这里啦。


该文章在 2025/6/26 18:54:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved