You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中Task生命周期是什么?何时结束及被GC回收?

关于C# Task生命周期、回收及单次执行场景的答疑

刚上手TPL(Task Parallel Library)很正常,咱们把你问的这些问题一个个掰明白:

1. Task的生命周期到底是啥样的?

Task从诞生到“寿终正寝”,会经历几个关键状态:

  • Created:用new Task(...)创建但还没启动时的状态(不过像Task.Factory.StartNew或Task.Run这种会直接启动任务,会跳过这个状态)
  • WaitingToRun:任务已经被调度,就等着线程池给它分配线程干活了
  • Running:任务正在执行中,代码在跑呢
  • RanToCompletion:任务顺顺利利执行完,没出岔子
  • Faulted:执行过程中抛出了没处理的异常,任务挂了
  • Canceled:通过CancellationToken成功取消了任务

你随时可以通过Task.Status属性查看任务当前处于哪个状态。

2. Task啥时候算结束?又啥时候会被GC回收?

  • 任务结束的标志:只要任务进入RanToCompletion、Faulted或Canceled这三个状态中的任意一个,就代表它已经完成了使命,彻底结束了。
  • GC回收的时机:和其他.NET托管对象一模一样——当没有任何代码持有这个Task对象的引用时,GC就会在合适的时机(比如内存压力大的时候)把它回收掉。哪怕任务还在运行,只要没代码拿着它的引用,GC也能回收Task对象本身(不过任务的执行会由线程池继续完成,不受影响)。

3. 单次执行的Task干完活后需要取消吗?GC会回收它不?

完全没必要取消!一次性任务干完活后,会自动进入RanToCompletion状态,已经是结束状态了——取消操作是给正在运行或者还没启动的任务准备的,对已经完成的任务来说,取消操作根本没用。

至于GC回收,只要这个Task对象没有被任何代码攥着引用(比如你示例里的局部变量),等它脱离作用域后,GC就会在合适的时候把它收走,完全不用担心内存泄漏的问题。

4. 你的示例代码具体会发生啥?

看你这段代码:

void DoSomething() { 
    Task task = Task.Factory.StartNew(()=>DoOneTimeWork()); 
}

当DoOneTimeWork()执行完毕后:

  1. 这个task对象会进入RanToCompletion状态(如果DoOneTimeWork没抛异常的话;要是抛了,就会进入Faulted状态);
  2. 当DoSomething()方法执行完,局部变量task就会离开作用域,此时没有任何根引用指向这个Task对象;
  3. 等.NET垃圾回收器下次执行回收时,这个Task对象就会被回收掉。

额外提一句:如果DoOneTimeWork()抛出了未处理的异常,在.NET Framework时代可能会导致进程崩溃,但在.NET Core及以后的版本里,未被观察到的Task异常不会搞崩进程了。不过还是建议你尽量处理任务的异常,比如用await等待任务并捕获异常,或者注册TaskScheduler.UnobservedTaskException事件来全局处理这类情况。

内容的提问来源于stack exchange,提问作者Rach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:20:51