✦

烜的小屋

烜的小屋
✦首页⌘项目◷归档♫音乐☁杂谈♡关于
封面

LuminTask:低分配 async/await 的一次系统化实践

写作时间:2026-07-29 20:10:00
# C#
# Async
# Zero GC
# Unity
◉0 次浏览

高频异步路径的成本

Task 是 .NET 生态最通用的异步抽象,但在游戏循环、框架内部和高频服务路径中,我们有时需要更强的生命周期约束与更少的托管堆分配。

LuminTask 提供可直接用于 async / await 的 LuminTask 与 LuminTask<T>。它通过自定义异步方法构建器、任务源池和非托管任务状态存储,尽可能减少预热后的重复分配。

直接作为异步返回值

using LuminThread;

static async LuminTask<int> CalculateAsync()
{
    await LuminTask.Yield();
    return 42;
}

var result = await CalculateAsync();

同步完成路径可以直接返回结果,不必人为制造一次异步调度:

static LuminTask<int> GetValue() => LuminTask.FromResult(123);

组合操作与互操作

库内提供 WhenAll、WhenAny、WhenEach、Delay、Yield、WaitUntil、Timeout 与 Forget 等常用操作,也支持和 Task、ValueTask 双向转换。

Task<int> task = CalculateAsync().AsTask();
LuminTask<int> luminTask = task.AsLuminTask();
ValueTask<int> valueTask = luminTask.AsValueTask();

对于回调式 API,可以使用 LuminTaskCompletionSource<T> 将外部完成信号桥接成 awaitable;取消令牌也可以直接转换为可等待任务。

不只是一个 Task 类型

LuminThread.AsyncEx 还提供一组非阻塞同步原语:

  • AsyncLock 与 AsyncReaderWriterLock
  • AsyncSemaphore
  • AsyncLazy<T>
  • AsyncManualResetEvent / AsyncAutoResetEvent
  • AsyncCountdownEvent 与异步条件变量

Unity 扩展则覆盖 PlayerLoop 调度、主线程切换,以及 Addressables、DOTween、TextMeshPro、YooAsset 等常见场景。

需要理解的单次消费约定

LuminTask 的使用语义更接近 ValueTask:一个实例应被 await 或 Forget() 消费一次,不应重复等待。这个限制使内部任务源可以在首次消费后安全归还池中,也是降低分配的重要基础。

性能不是免费午餐。选择这类抽象时,需要让团队理解所有权、取消与异常传播规则,并用真实工作负载进行基准测试。

项目源码:TheLight-233/LuminTask

💬

评论区准备中

已移除模板中存在安全风险的旧 Gitalk 依赖。新的 GitHub Discussions 评论系统接入前,可以通过邮箱与我交流。

发送邮件
avatar

Light

专注高性能 C#、.NET Runtime、Unity 与网络基础设施,把对性能的执着写进每一行代码。

RECOMMENDED

LuminCLR:用 C++17 探索 .NET Runtime 与 AOT

2026-07-24 22:00:00

LuminNet:从传输层到强类型 RPC 的高性能网络框架

2026-07-18 19:45:00

LuminPack:为 C# 与 Unity 打造的高性能序列化

2026-08-01 21:30:00

Table of Contents