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方法在一个数据库中创建和启动任务
活动如果需要,这是创建和启动任务的首选方法
创建和计划不必分开
为此,我们必须深入研究任务。任务本质上是线程,在其起源中,任务是为线程池调度的。现在考虑一下这个词:
任务本质上是线程;但它们是背景线程。
当所有前台线程
线程完成。所以,如果你不做任何事情的任务和
程序结束时,任务可能无法完成
因此,您可能会认为,如果后台线程在所有前台线程完成时自动中止,则必须保留对任务的引用,事实上,这就是您应该始终等待中提到的任务的原因
但是让我们深入到下面这行:
一旦创建线程对象,就不必保留对该线程对象的引用
已经开始了线程。线程继续执行,直到
线程程序已完成
这意味着,尽管上面提到后台线程在所有前台线程完成时自动中止,但不需要保留对它的引用。