3

为了帮助提高客户端的性能,我将请求的处理卸载到任务上。这样做是因为处理通常需要一些时间,而且我不希望客户端等待一段时间才能获得 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
    }
}

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

4

2 回答 2

6

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

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

于 2013-01-25T17:27:02.127 回答
4

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

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

菲尔·哈克的更多信息

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

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

于 2013-01-25T17:26:47.597 回答