【问题标题】:When using Async/Await in C# are tasks terminated automatically when program exits?在 C# 中使用 Async/Await 时,任务是否会在程序退出时自动终止?
【发布时间】:2021-01-28 17:28:31
【问题描述】:

如果我调用了多个仍在等待的异步函数,并且程序在主线程上退出,是否仍在等待的任务会自动清理?或者,我是否需要确保在程序退出时手动清理任务?

在调用异步函数时特别询问,而不是使用new Thread()

此外,在这种特定情况下,Task 指的是在调用async 函数并等待结果时生成的System.Threading.Tasks.Task

似乎在 MSDN 中找不到答案(除非我找错地方了)。

【问题讨论】:

  • 如果您使用new Thread(),它们不会被“自动”清理。
  • async Tasks 和new Thread() 创建的线程是完全不同的东西。此外,对于线程,您还可以设置IsBackground 属性。通常,当Main() 函数退出时,运行时确实等待前台线程,但不等待后台线程或任务IsBackground 当然,如果运行时不等待线程/任务完成,它们可能处于某种不确定的状态,这可能会导致数据损坏。
  • 问题的标题与问题的正文不一致。标题询问任务,正文询问线程。你能edit这个问题并修正标题或正文吗?
  • @KJanek 在这种情况下我没有使用new Thread()
  • @TheodorZoulias 更新了问题和文本。希望它更清楚

标签: c# multithreading async-await background-process


【解决方案1】:

等待的任务是否还在自动清理?

如果等待任务,则程序不会在任务完成之前退出。所以如果程序退出,这意味着任务没有等待。或者他们在一个本身没有等待的任务中等待。或者它们在 async void 方法中等待,根据定义,该方法不等待(async void 方法不返回任何可以等待的内容)。

所以我假设您正在处理未等待的任务,或者换句话说,处理的是即发即弃的任务。在大多数情况下,这些任务在IsBackground 属性等于true 的线程上运行,或者根本不在any thread 上运行。这些任务将在任意执行点自动终止。但是,启动在前台线程上运行的任务并非不可能,在这种情况下,程序将在任务完成时终止,或者当程序从任务管理器中终止时终止。

【讨论】:

  • 你的第一句话是假的。程序完全有可能在有不完整的任务时退出,甚至是不完整的任务分配给它们的延续。
  • @Servy 我指的是等待的任务,“等待”是指应用程序的主线程最终会直接或间接地等待它们。也许“扎根”这个词比“等待”这个词更能传达我想说的意思。
  • 短语“主要方法等待的任务”和“等待的任务”之间存在巨大的区别。如果你说的是前者,那你就不应该说后者。此外,main 方法等待的任务与讨论 main 方法完成后未完成的任务会发生什么无关。如果 main 方法等待它们,那么根据定义,当 main 方法完成时它们不是不完整的。
  • @Servy 在这个答案中我使用了“等待”的更严格的定义。我认为“等待”与“即发即弃”相反,因此它排除了不属于到达Main 方法的await 链的一部分的任务。我采用这个定义的原因是因为 OP 指的是“仍在等待”的任务,而不是“仍在运行”的任务。这表明他们可能对他们的任务不仅在运行,而且还在等待这一事实有一些额外的期望。该答案的第一段试图解决这些期望。
  • @Servy 是的,但是用这个 11 个单词的短语替换我的答案中的每个“等待”实例,这将是一个绝对糟糕的答案。你能提出一个更简短的方式来描述这个概念吗? “成为到达Main 方法的await 链的一部分”是一个非常重要的概念,所以它应该有一个可用的名称,你不觉得吗?
【解决方案2】:

https://medium.com/@hasangi/lets-talk-about-parallelism-in-net-baby-2a69ba53f986

线程默认创建为前台进程(可设置为在后台运行),任务创建为后台进程。当任何前台进程正在运行时,应用程序不会终止。但是,即使后台进程正在运行,应用程序也会在所有前台进程完成后终止。因此,即使没有完成任务也会终止。

如果我们不能创建在前台线程中运行的任务,那么答案是肯定的,未等待的任务将始终在程序退出时终止。

【讨论】:

  • 该来源中至少 3/4 的内容实际上是不准确的,您根本不应该依赖该来源。
  • 您可以找到here 的示例,说明如何创建在前台线程上运行的任务。
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 2023-03-30
  • 1970-01-01
  • 2023-03-16
  • 2012-04-29
  • 1970-01-01
相关资源
最近更新 更多