【问题标题】:When does a C# Task terminate?C# 任务何时终止?
【发布时间】:2018-11-26 21:45:42
【问题描述】:

我正在使用 ASP.NET。当我运行一个新任务时,该任务将在什么时候终止?当调用它的线程终止时它会终止吗?还是会一直运行到我的 lambda 表达式中的代码运行完毕?

这是我正在尝试做的一个示例:

Task.Run(() =>
{
    try
    {
        MyFunction();
    }
    catch (Exception ex)
    {
        Console.Write(ex);
    }
});

MyFunction() 不返回任何内容,我只是希望它自己开始运行,以便当前线程可以继续。当我运行我的应用程序并调用此代码时,它似乎工作得很好。我只是想看看我是否应该担心任务会自发终止,或者我是否会没事。

我还应该提到,发出请求的线程可能会在任务完成之前终止。

谢谢。

【问题讨论】:

  • 请永远不要写catch (Exception ex) - 这就像糟糕的反模式。阅读Eric Lippert's Vexing Exceptions
  • @Enigmativity 这篇文章很棒!其实我以前读过。我有这样的异常处理只是为了表明我正在尝试捕获,我不想透露任何特定于我的代码库的内容,因为这是我在工作中正在做的事情。
  • 这是一种设计选择。监视线程是否有错误是一种很好的做法,有多种方法可以做到这一点,但这不是必需的。如果您对自己的方法有信心,那么就照原样去做吧;可能会添加一些日志记录。就任务而言;这将在您的应用程序终止时终止,否则无论范围如何,它都会继续运行。
  • @TheGeneral 并不是说​​,我觉得 OP 是在询问线程是继续还是在范围内死亡。一个任务,例如这个任务,只要它在范围内或被引用,就会一直存在,它运行的线程(如果它创建一个)将一直运行到代码完成或应用程序结束。在这种情况下,可能的线程和任务都结束了。

标签: c# asp.net multithreading task


【解决方案1】:
  1. 任务在执行完任务代码后不久就结束了它的生命周期。

  2. 当任务超出范围时,它最终会被垃圾收集器清理,前提是没有代码可以执行

最后没有充分的理由为什么任务应该突然结束,除非抛出异常并且不能被捕获。

.net。不会掷骰子来终止任务,否则它们将毫无用处。他们活多久就活多久,然后很快就终止了

从技术上讲,这将使用线程池线程并将其返回到池中,但它们只是语义

https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming

【讨论】:

    【解决方案2】:

    Task 可能有也可能没有线程,但在您的Task.Run 的情况下应该有。您可以引用Task 本身,只要它在范围内,或者您保持对它的有效引用,它就会一直存在。它运行的线程将继续运行,直到代码完成。这有点令人困惑,但知道Task 本身和正在运行的线程是分开的。 Task,更像是某些工作的状态/经理,它可能在也可能不在单独的线程上。如果需要,可以保留此引用直到应用程序终止,您可以在其中读取工作状态,即使它已完成。

    如果Task 离开范围并且没有引用,它监控的工作单元将继续;但是,Task 本身将在完成后设置为垃圾收集。换句话说,您可以根据需要触发并忘记Task,除非出现错误或您结束应用程序,否则分配给Task 的工作单元将完成。

    请注意,Task 将随您的应用程序终止,如果 Task 确实产生了一个新线程,例如您正在使用 Task.Run,它也会在您的应用程序结束时终止。

    【讨论】:

    • 当它执行完分配给任务的代码时它是否也会终止?还是我需要手动终止它?
    • 是的。线程将终止,Task 将超出范围并被垃圾回收。如果任务在完成之前超出范围,除非您的应用程序结束,否则它仍然会完成。你不需要手动终止任务,除非它被设置为无限运行,在这种情况下你应该或者它会在应用程序结束时自行终止。
    猜你喜欢
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多