当前位置: 首页 > news >正文

UnitTask中的Forget()与 CTS

🎯 结论先行:不是“每个异步方法”都要加 CTS

而是「凡是可能长时间存在、或受生命周期控制的任务」才应该加 CTS。


🧩 一、Forget()CTS 的核心区别

对比项 .Forget() CancellationTokenSource
目的 忽略等待结果 控制任务生命周期
适用场景 轻量、短期任务 长时、可取消任务
是否能终止任务 ❌ 否 ✅ 可以取消
是否捕获异常 ❌ 默认丢弃(除非 .Forget(ResultHandling...)) ✅ 可被 try-catch 捕获
GC 开销 少量(每次创建)

🧭 二、两者协同工作的黄金范式

最佳做法是:

👉「任务逻辑用 CTS 控制生命周期」,
👉「调用者决定是否 await.Forget()」。

示例:

private CancellationTokenSource cts;private void Start()
{cts = new();LoadSceneAsync(cts.Token).Forget(); // 调用方选择忽略
}private async UniTask LoadSceneAsync(CancellationToken token)
{await UniTask.Delay(5000, cancellationToken: token);Debug.Log("场景加载完成");
}private void OnDestroy()
{cts.Cancel(); // 防止场景切换或对象销毁时任务泄漏
}

💡 解释:

  • LoadSceneAsync 不关心是否被 await;

  • cts.Token 决定任务是否继续;

  • Forget() 让调用方不阻塞,但内部仍受控。


⚙️ 三、什么时候“必须”加 CTS?

场景 是否建议加 CTS 原因
⏳ 延迟逻辑(如 Delay, WaitUntil) ✅ 是 避免对象销毁后继续等待
🔄 循环任务(如 AI 行为、监控) ✅ 是 必须能中断
🌐 异步加载(网络/资源) ✅ 是 用户可能切场景、关闭窗口
⚡ 短期逻辑(如 UI 动画) ❌ 可省略 生命周期很短
🧩 同步逻辑(例如计算) ❌ 不必要 一次执行完即结束
🧠 Editor 模式(非运行时) ✅ 推荐 编辑器中生命周期不稳定

🧱 四、实际对比:有无 CTS 的差异

❌ 无 CTS(任务泄漏)

private async void Start()
{await UniTask.Delay(5000);Debug.Log("对象早就销毁了,但我还在执行!");
}

✅ 有 CTS(安全终止)

private async void Start()
{var token = this.GetCancellationTokenOnDestroy();await UniTask.Delay(5000, cancellationToken: token);Debug.Log("对象没销毁才会执行到这里");
}

💡 说明:

GetCancellationTokenOnDestroy() 是 UniTask 为 MonoBehaviour 提供的神器,它会在对象销毁时自动取消。


🧩 五、关于 Forget() 的使用建议

✅ 推荐写法:

SomeAsync().Forget(); // 我知道它会跑完,不需要返回结果

⚠️ 不推荐写法:

await SomeAsync().Forget(); // 无意义,Forget返回void

🚨 异常丢失问题:

.Forget() 默认吞异常,你可以这样防御:

SomeAsync().Forget(e => Debug.LogException(e));

🧠 六、实战建议(通俗记忆法)

任务类型 是否加 CTS 是否 Forget
UI 动画
网络请求 ❌(要 await 结果)
AI 行为循环
Editor 扩展操作
一次性逻辑
场景加载 ❌(等待完成)

🔍 七、进阶:组合式 CTS 管理

你可以用一个父级 Token 控制多个异步任务:

var cts = new CancellationTokenSource();DoA(cts.Token).Forget();
DoB(cts.Token).Forget();
DoC(cts.Token).Forget();// 一键取消所有
cts.Cancel();

或者组合多个 Token:

var linked = CancellationTokenSource.CreateLinkedTokenSource(token1, token2);
await UniTask.Delay(1000, cancellationToken: linked.Token);

📈 八、性能注意

  • 创建一个 CTS 的开销 ≈ 40~60B GC Alloc;

  • 所以:
    👉 建议在 MonoBehaviour 级别缓存
    👉 而不是每次 async 方法都 new 一个。

private CancellationTokenSource cts;
private void Awake() => cts = new();
private void OnDestroy() => cts.Cancel();

🧩 九、最佳实践模板(生产级推荐)

public class Example : MonoBehaviour
{private CancellationTokenSource _cts;private void Awake(){_cts = new();}private void OnDestroy(){_cts.Cancel();_cts.Dispose();}private void Start(){RunAsync(_cts.Token).Forget();}private async UniTask RunAsync(CancellationToken token){while (!token.IsCancellationRequested){await UniTask.Delay(1000, cancellationToken: token);Debug.Log("持续工作中...");}}
}

🧠 记忆口诀

Forget 是“不管结局”,CTS 是“能中断结局”。

  • 只要任务可能「超时、循环、依赖对象存在」,就加 CTS

  • 调用方只关心“我是否等待结果”,就用 Forget

http://www.zskr.cn/news/19135.html

相关文章:

  • 12 种 Pandas 测试技巧,让数据处理少踩坑
  • 02020506 EF Core高级06-EF Core批量删除更新插入、全局筛选器、软删除、全局筛选的性能问题
  • 一种整理HTML和JS代码的方法
  • 元推理框架,是人类文明的《神农本草经》,源于自指自洽的觉悟与洗礼
  • 【程序员必看】MySQL数据类型全解析:选错类型性能直接掉80%!
  • 2025环氧地坪漆厂家推荐:常州新禾,品质保证施工无忧!
  • 2025家居ERP推荐:赛思软件助力企业高效管理!
  • 2025彩钢瓦保养优质厂家推荐,江苏承优建筑工程专业服务!
  • 2025磁力泵加工厂推荐中正化工,专业定制高效耐用产品!
  • 2025双氧水供应厂家推荐:苏州市岚昱化工品质卓越选择!
  • 2025上海保洁公司最新推荐榜:高效清洁与贴心服务的优质选择
  • 2025书包柜定做厂家推荐:杰尚家具专业定制,品质卓越!
  • 打不动十个
  • 2025拉伸器厂家最新推荐榜:专业制造与优质服务的行业佼佼者
  • 2025氧化镁供应厂家推荐:松辽镁业高纯度优质选择!
  • 2025硅藻土订制厂家口碑推荐:品质卓越与专业服务的双重保障
  • 2025数控滚齿机订做厂家推荐:吉莱特智能装备,精准高效品质
  • Agno - 轻量级Python多智能体系统框架
  • P10960 SUBSTRACT 个人题解
  • 2025新型千斤顶厂家推荐:柳州市联桥科技,品质卓越服务到位
  • 2025年PP鱼池优质厂家推荐:超众渔业机械,环保耐用首选!
  • 完整教程:MongoDB Ops Manager部署
  • 2025医疗器械微弧氧化优质厂家推荐,华源漆业技术领先服务到
  • 【网络协议】SSL与TLS的关系 - 教程
  • 2025年安全光栅厂家最新推荐榜:精准防护与高效性能的工业首
  • 2025七水硫酸锌实力厂家推荐:安通环保科技,品质卓越信赖之
  • 2025磁力泵厂家最新推荐榜:高效稳定与优质服务的首选指南
  • 2025智能防爆灯厂家最新推荐榜:安全高效与技术创新典范
  • 2025氢氧化镁供应厂家推荐:辽宁润辉新材料科技优质厂家首选
  • 2025黄金回收品牌最新推荐榜:高信誉与专业服务的首选厂家!