Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我是否需要保留对`Task.Run`方法返回的`Task`的引用?_C#_.net_Async Await_Task Parallel Library - Fatal编程技术网

C# 我是否需要保留对`Task.Run`方法返回的`Task`的引用?

C# 我是否需要保留对`Task.Run`方法返回的`Task`的引用?,c#,.net,async-await,task-parallel-library,C#,.net,Async Await,Task Parallel Library,如果我有一个异步方法: async Task Process() { while (condition) { await ...; } } 我需要安排这个方法的执行。因此,我使用: Task.Run(Process); 我是否需要保留Task.Run方法返回的Task对象的引用,以确保Process执行到完成 这里有更多的上下文:我需要在我的应用程序中创建很多(大约50K)任务队列。因此,我想创建一个无线程队列处理设计,当队列为空(大多数队列都是空的

如果我有一个异步方法:

async Task Process()
{
    while (condition)
    {
        await ...;
    }
}
我需要安排这个方法的执行。因此,我使用:

Task.Run(Process);
我是否需要保留
Task.Run
方法返回的
Task
对象的引用,以确保
Process
执行到完成


这里有更多的上下文:我需要在我的应用程序中创建很多(大约50K)任务队列。因此,我想创建一个无线程队列处理设计,当队列为空(大多数队列都是空的)时,它没有成本(除了内存)


示例类的要点:

一般来说,您不应该丢弃任务。这不是关于确保任务将运行(它将运行1),而是关于观察异常。如果您没有对
任务执行操作,那么发现问题的唯一方法就是添加事件处理程序。不理想

最好让
等待它的代码进入
try
/
catch
块中,或者注册一个
ContinueWith
处理程序,在该处理程序中指定在发生故障时应调用您

不幸的是(IMO),在4.5版本前后.NET的行为发生了变化,因此未观察到的异常不再破坏该过程。这意味着,如果您没有观察到它们,那么代码就会失败,并且无法跟踪/记录这种情况


通常,围绕已经生成任务的方法运行任务是不必要的,而且会适得其反。该方法已经承诺交付一个
任务
——为什么要用第二个任务来包装它?(该方法返回
任务的方式和原因是该方法的实现细节,与调用方无关)。只有当您正在调用的方法执行了大量CPU限制的工作,并且您(调用者)当前处于“宝贵”上下文中(例如在UI线程上)时,才应该真正执行此操作



1恢复整个过程会持续足够长的时间,等等。

一般来说,您不应该放弃任务。这不是关于确保任务将运行(它将运行1),而是关于观察异常。如果您没有对
任务执行操作,那么发现问题的唯一方法就是添加事件处理程序。不理想

最好让
等待它的代码进入
try
/
catch
块中,或者注册一个
ContinueWith
处理程序,在该处理程序中指定在发生故障时应调用您

不幸的是(IMO),在4.5版本前后.NET的行为发生了变化,因此未观察到的异常不再破坏该过程。这意味着,如果您没有观察到它们,那么代码就会失败,并且无法跟踪/记录这种情况


通常,围绕已经生成任务的方法运行任务是不必要的,而且会适得其反。该方法已经承诺交付一个
任务
——为什么要用第二个任务来包装它?(该方法返回
任务的方式和原因是该方法的实现细节,与调用方无关)。只有当您正在调用的方法执行了大量CPU限制的工作,并且您(调用者)当前处于“宝贵”上下文中(例如在UI线程上)时,才应该真正执行此操作



1恢复整个过程需要足够长的时间,等等。

为此,我们必须深入研究任务。任务本质上是线程,在其起源中,任务是为线程池调度的。现在考虑一下这个词:

任务本质上是线程;但它们是背景线程。 当所有前台线程 线程完成。所以,如果你不做任何事情的任务和 程序结束时,任务可能无法完成

因此,您可能会认为,如果后台线程在所有前台线程完成时自动中止,则必须保留对
任务的引用,事实上,这就是您应该始终等待中提到的任务的原因

但是让我们深入到下面这行:

一旦创建线程对象,就不必保留对该线程对象的引用 已经开始了线程。线程继续执行,直到 线程程序已完成

这意味着,尽管上面提到后台线程在所有前台线程完成时自动中止,但不需要保留对它的引用

事实上,根据文档,创建任务的正确方法是使用其工厂:

您还可以使用StartNew方法在一个数据库中创建和启动任务 活动如果需要,这是创建和启动任务的首选方法 创建和计划不必分开


为此,我们必须深入研究任务。任务本质上是线程,在其起源中,任务是为线程池调度的。现在考虑一下这个词:

任务本质上是线程;但它们是背景线程。 当所有前台线程 线程完成。所以,如果你不做任何事情的任务和 程序结束时,任务可能无法完成

因此,您可能会认为,如果后台线程在所有前台线程完成时自动中止,则必须保留对
任务的引用,事实上,这就是您应该始终等待中提到的任务的原因

但是让我们深入到下面这行:

一旦创建线程对象,就不必保留对该线程对象的引用 已经开始了线程。线程继续执行,直到 线程程序已完成

这意味着,尽管上面提到后台线程在所有前台线程完成时自动中止,但不需要保留对它的引用。