【问题标题】:HostingEnvironment.QueueBackgroundWorkItem - Clarification?HostingEnvironment.QueueBackgroundWorkItem - 澄清?
【发布时间】:2019-11-15 23:30:50
【问题描述】:

我已阅读 Stephen's article 关于在 Asp.net 中触发并忘记后台操作的内容。

不建议使用Task.Run 进行即发即弃,因为 Asp.net 不知道您已将任务排队。

因此,如果即将发生回收,则任务无法知道它。
这就是HostingEnvironment.QueueBackgroundWorkItem 进入的地方。

它将知道回收即将发生,并将调用取消令牌。

但是!

FWIK - 一旦主线程完成,后台任务就会被“终止”。

这意味着如果请求进入(正在创建/获取新线程)并调用Task.Run,并且响应已完成(但 Task 尚未完成),则 Task 将被终止。

问题:

QueueBackgroundWorkItem 能解决这个问题吗?还是只存在警告回收? 换句话说,如果有一个运行QueueBackgroundWorkItem的请求并且响应已经完成,那么QueueBackgroundWorkItem会继续执行它的代码吗?

文档说:“独立于任何请求”,但我不确定它是否回答了我的问题

【问题讨论】:

    标签: c# asp.net .net multithreading background-process


    【解决方案1】:

    根据documentation,此方法尝试延迟应用程序关闭,直到后台工作完成。

    与普通的 ThreadPool 工作项不同,ASP.NET 可以跟踪通过此 API 注册的工作项当前正在运行的数量,并且 ASP.NET 运行时将尝试延迟 AppDomain 关闭,直到这些工作项完成执行.

    此外,它不会处理与当前请求相关联且不适合独立于请求的后台工作的某些上下文:

    此重载方法不会将 ExecutionContext 或 SecurityContext 从调用者流向被调用者。因此,这些对象的成员(例如 CurrentPrincipal 属性)不会从调用者流向被调用者。

    在 ASP.NET 中,无法确保后台工作完成。机器可能蓝屏,可能存在终止工作进程的错误,可能存在超时强制终止等等。

    或者,您的代码可能存在错误并崩溃。这也会导致排队的工作丢失。

    如果您需要可靠地执行某些操作,请在确认完成之前同步执行它,或者将其排队到某个地方(消息队列、数据库等)。

    这意味着如果一个请求进入(正在创建/获取一个新线程)并且它调用Task.Run,​​并且响应已经完成(但Task尚未完成),那么Task将被终止。

    不,Task.Run 独立于 HTTP 请求工作。事实上,除非任务的代码自行取消,否则无法取消 Task

    【讨论】:

    • 抛开asp.net,如果我们有一个主线程和一个后台线程,并且主线程已经完成,这将导致后台线程也被终止。这是 IsBackGround 定义。现在....任务是后台线程。所以我再次问,如果一个请求线程已经完成了它的响应,那么来自该请求的 inoked 任务是否会继续(即使它是一个后台线程)? QueueBackgroundWorkItem 会影响行为吗?
    • IsBackground 控制所有非后台线程退出时发生的情况。只要工作进程不想退出,所有后台线程就一直运行。 IsBackground 仅在 ASP.NET 想要 退出时才重要。然后,运行时可以终止后台线程。线程不以任何方式连接。运行时不理解“请求线程”的概念。此外,一个工作进程中同时运行着许多请求。
    • 尝试回收时,Task.Run 不会完成,但 QueueBackgroundWorkItem 会。至少它会尝试。 ASP.NET 无法等待 Task.Run,​​因为它不知道它的存在。
    • 所以Task.Run 是可靠的(假设在不久的将来不会回收),无论请求线程如何,都不会被 gc'ed。对吗?
    • 是的._______________
    猜你喜欢
    • 2013-06-05
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2020-07-30
    • 2020-04-02
    相关资源
    最近更新 更多