如果我在方法中有以下代码块(使用 .NET 4 和任务并行库):
var task = new Task(() => DoSomethingLongRunning());
task.Start();
并且方法返回,该任务会超出范围并被垃圾收集,还是会运行完成?我没有注意到 GCing 有任何问题,但我想确保我没有为 GC 设置竞争条件。
如果我在方法中有以下代码块(使用 .NET 4 和任务并行库):
var task = new Task(() => DoSomethingLongRunning());
task.Start();
并且方法返回,该任务会超出范围并被垃圾收集,还是会运行完成?我没有注意到 GCing 有任何问题,但我想确保我没有为 GC 设置竞争条件。
更新:
在我回答了这个问题之后(很久以前!),我发现任务总是运行到完成是不正确的 - 有一个小的,比如说“角落”案例,任务可能无法完成。
原因是这样的:正如我之前回答的那样,任务本质上是线程;但它们是后台线程。当所有前台线程完成时,后台线程会自动中止。因此,如果您对任务不做任何事情并且程序结束,则任务可能无法完成。
您应该始终等待任务。可以在Jon 给我的出色回答中找到更多信息。
原来的:
任务被调度到 ThreadPool,这意味着它们本质上是线程¹(实际上,它们封装了线程)。
从线程文档:
启动线程后,不必保留对 Thread 对象的引用。线程继续执行,直到线程过程完成。
所以,不,没有必要保留对它的引用。
此外,文档指出创建任务的首选方法是使用它的工厂:
您还可以使用 StartNew 方法在一次操作中创建和启动任务。如果创建和调度不必分开,这是创建和启动任务的首选方式 (...)
希望能帮助到你。
¹根据文档:
任务表示异步操作,在某些方面它类似于创建新线程或 ThreadPool 工作项,但抽象级别更高。
该任务将运行完成。即使没有任何其他对它的引用(我相信没有被生根是这个词),线程池仍然会持有对它的引用,并至少防止它被垃圾收集(我至少说,因为即使完成后,不能保证它会被垃圾收集)直到完成。