.NET Task 实例可以在运行期间超出范围吗?

Can .NET Task instances go out of scope during run?(.NET Task 实例可以在运行期间超出范围吗?)
本文介绍了.NET Task 实例可以在运行期间超出范围吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在方法中有以下代码块(使用 .NET 4 和任务并行库):

If I have the following block of code in a method (using .NET 4 and the Task Parallel Library):

var task = new Task(() => DoSomethingLongRunning());
task.Start();

然后方法返回,该任务会超出范围并被垃圾收集,还是会运行完成?我没有注意到 GCing 有任何问题,但我想确保我没有为 GC 设置竞争条件.

and the method returns, will that task go out of scope and be garbage collected, or will it run to completion? I haven't noticed any issues with GCing, but want to make sure I'm not setting myself up for a race condition with the GC.

推荐答案

更新:

在我回答了这个问题之后(很久以前!),我发现任务总是运行到完成是不正确的 - 有一个小的,比如说角落"的情况,任务可能无法完成.

After I answered this question (a long time ago!) I found out that it's not true that Tasks will always run to completion - there's a small, let's say "corner" case, where tasks may not finish.

原因是这样的:正如我之前回答的那样,任务本质上是线程;但它们是 background 线程.当所有前台线程完成时,后台线程会自动中止.因此,如果您对任务不做任何事情并且程序结束,则任务可能无法完成.

The reason for that is this: As I have answered previously, Tasks are essentially threads; but they are background threads. Background threads are automatically aborted when all foreground threads finish. So, if you don't do anything with the task and the program ends, there's a chance the task won't complete.

您应该始终等待任务.更多信息可以在 Jon 给我的优秀答案上找到.

You should always await on tasks. More information can be found on the excellent answer Jon gave me.

原文:

任务被调度到 ThreadPool,这意味着它们本质上是线程¹(实际上,它们封装了线程).

Task are scheduled to the ThreadPool, meaning that they are essentially threads¹ (actually, they encapsulate threads).

来自 线程文档:

没有必要保留一旦你引用一个 Thread 对象已经启动线程.线程继续执行直到线程程序完成.

It is not necessary to retain a reference to a Thread object once you have started the thread. The thread continues to execute until the thread procedure is complete.

所以,不,没有必要保留对它的引用.

So, no, there is no need to retain a reference to it.

此外,文档 指出创建任务是使用它的工厂:

Also, the documentation states that the preferred way to create a Task is to use it's factory:

您也可以使用 StartNew 方法一次创建和启动一项任务手术.这是首选方式创建并启动任务(如果创建)和调度不必是分开(...)

You can also use the StartNew method to create and start a task in one operation. This is the preferred way to create and start tasks if creation and scheduling do not have to be separated (...)

希望对你有帮助.

¹ 根据文档:

一个任务代表一个异步操作,并且在某些方面它类似于创建一个新线程或 ThreadPool 工作项,但在更高层次的抽象.

A task represents an asynchronous operation, and in some ways it resembles the creation of a new thread or ThreadPool work item, but at a higher level of abstraction.

这篇关于.NET Task 实例可以在运行期间超出范围吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)