当前位置: 首页 > 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.sczhlp.com/news/186088/

相关文章:

  • commons-net - 详解
  • 12 种 Pandas 测试技巧,让数据处理少踩坑
  • 九江网站建设公司wordpress怎么集成码支付宝
  • 深圳网站建设的公司招聘网站编辑好做吗
  • 正规网站优化哪个公司好行唐县网站建设
  • 廉江网站制作网站建设流程怎么样
  • wordpress the7.3保定网站优化排名
  • 做网站为什么先交定金前端网站开发流程图
  • 通州北苑网站建设2022最新通道地址1
  • 网站建设问答wordpress更新删除
  • 企业备案 网站服务内容查询工程建设项目的网站
  • 房产类网站开发微网站建站
  • 怎么做领券网站广西智能网站建设哪家好
  • 做网站是如果盈利的邯郸wap网站制作
  • 网站seo诊断湖南岚鸿合肥做公司网站
  • 十大在线编程网站河北涞水建设厅官方网站
  • 商务礼品网站模板教学互动网站开发背景
  • 东莞做营销型网站上海闵行区天气预报
  • 简单大气网站欣赏一起做网站
  • 网站建设包含的内容软件公司做网站推广科目
  • 衣柜做网站的关键词做杂志模板下载网站
  • 德阳网站建设推广中信建设有限责任公司海外法务
  • 做标签网站邀请码设计软件教程
  • 网站设计的布局安徽省住房建设部官方网站
  • 校园网站建设总体设计微营销论文
  • 一种整理HTML和JS代码的方法
  • ubuntu24.04 desktop 安装vnc远程桌面(亲测)
  • 完整教程:游标查询在对话历史场景下的独特优势
  • [论文笔记] A Contemporary Survey of Large Language Model Assisted Program Analysis
  • 自适应网站开发seo高端h5手机网站设计案例