IIS 回收时正在运行的任务会发生什么

JG *_* SD 3 c# asp.net iis iis-7.5 c#-4.0

为了帮助提高客户端的性能,我将请求的处理卸载到任务上。这样做是因为处理通常需要一些时间,而且我不希望客户端为了获得 200 响应而等待一段时间。将工作卸载到任务上的 Web 服务始终在处理帖子。

public void ProcessRequest(HttpContext context)
{
    // check for bad requests -- return 400

    // get copy of the context input stream

    Task.Factory.StartNew(() =>
    {
        ProcessRequest(contextInputStreamCopy);
    });
}

private void ProcessRequest(Stream inputStream)
{
    try
    {
        // process input stream
    }
    catch(Exception ex)
    {
        // any server error that would normally result in 500 response are not
        // exposed to the clients, the clients are to see 200 when the server 
        // encounters an error
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是当 IIS 回收或网站停止时这些任务会发生什么。

cuo*_*gle 6

\n

IIS 回收时正在运行的任务会发生什么情况

\n
\n\n

当 IIS 回收时,它只是相应地降低正在运行的任务。如果您的任务需要一点时间,您应该考虑在单独的进程上运行您的任务。纠正方法是使用队列(MSMQ、RabbitMQ...)来存储任务并使用另一个进程从队列中选择要运行的任务。为此,您可以使用带有调度程序的 Windows 服务或控制台主机。

\n\n

菲尔·哈克提供的更多信息

\n\n
\n

当 ASP.NET 拆除 AppDomain 时,它将尝试刷新现有请求,并在拆除 App Domain 之前给它们时间完成。ASP.NET 和 IIS 会考虑它们知道正在运行的代码,例如作为请求的一部分运行的代码。

\n\n

问题是,ASP.NET 不知道使用计时器或类似机制生成的后台线程上完成的工作。它只知道与请求相关的工作。

\n
\n


Ari*_*tos 6

当 IIS 回收时,它会等待所有线程完成并退出 - 直到池中的超时值。在那段时间之后,他们会杀死所有正在运行的线程并重新开始。

因此,当应用程序请求关闭globa.asax使用这些Application_End功能时,您可以向您的线程设置一个信号以停止。

  • 如果我在创建任务时将任务添加到列表中,然后在“Application_End”中执行“Task.WaitAll”,会等到所有任务都完成吗?由于它确实出现,我偶尔会出现线程中止,并且它使数据处于不良状态。 (2认同)
  • @JGinSD 是的,您也可以这样做 - 我已经这样做了,并且还发出停止信号。但我说你他们等待超时值。如果可以,您可能需要在池中加注和超时值。 (2认同)
  • 啊,所以即使我在“Application_End”中等待它仍然可能达到超时。 (2认同)
  • @JGinSD 是的,可以等待多长时间有超时。池上的`关闭时间限制(秒)` (2认同)