ASP.NET HTTPHandlers和长时间运行的进程

时间:2009-03-05 23:09:26

标签: asp.net ajax xmlhttprequest httphandler

这是一个多部分问题。

我有一个可能需要几分钟才能完成的过程,它是通过使用异步javascript请求调用HTTPHandler来运行的。

问题1:如何确保此请求不会在服务器和客户端都超时?

问题2:在最终页面完成之前发送回XmlHttpRequest对象的处理时,是否可以从HTTPHandler发出数据?

我想计算实际工作量和完成的回报百分比。我猜这是可能的。

任何提示?

编辑:

快速测试:

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        for (int i = 0; i < 100; i++)
        {
            context.Response.Write("Hello World " + i + Environment.NewLine);
            System.Threading.Thread.Sleep(500);
            context.Response.Flush();
        }            
    }

将Hello World逐位推送到客户端......这适用于同步请求,我将看看xmlHttpRequest是否为每一行获取了readystatechange事件。

我总是避免在ASP.NET应用程序上进行多线程处理,因为你无法控制工作进程何时会死,这会导致所有生成的线程死亡。

相反,当IIS已经为您执行此操作时,为什么要重新创建一个单独的线程池。

6 个答案:

答案 0 :(得分:1)

我过去所做的是在新线程上启动长时间运行的进程,并在进程类上有一个属性,表示%complete。然后,每隔一段时间,浏览器就可以对一个只调查%complete属性的HttpHandler进行AJAX调用。这样HttpHandler就会立即返回。

如果作业很重要,可能需要考虑一些问题,例如减轻工作进程回收中间作业或保存作业状态以便重新启动。如果作业非常关键,最好编写执行作业的Windows服务,并使用Remoting或其他内容来查询进度。

答案 1 :(得分:0)

  1. 您可以在web.config中更改请求超时值,例如: <configuration> <system.web><httpRuntime executionTimeout="1000" /></system.web></configuration>

  2. 据我所知,无法在同一异步请求中发回信息。我见过的大多数Ajax UI都是通过拥有一个包含正在运行的任务的统计信息的静态类来创建该行为,然后使用另一个异步请求或iframe轮询该行为。类似的一个很好的例子是Neat Upload Control

答案 2 :(得分:0)

这是一个想法......

如果您有一个需要“几分钟”处理的进程,那么最好创建一个单独的线程(或单独的线程队列),而不是使用ASP.NET工作线程。这是因为如果您耗尽所有工作线程,那么您的Web服务器可能会挂起。有关此问题的详细信息:http://msdn.microsoft.com/en-us/magazine/cc164128.aspx

您的第一个AJAX请求是启动该过程。后续调用将获取进程的状态,包括%完成。使用计时器进行轮询(每隔几秒或其他似乎最好的工作)以完成%完成。直到完成所有操作。

AJAX请求(XmlHttpRequest)在客户端上没有超时(http://luke.breuer.com/tutorial/xmlhttprequest.aspx ...向下滚动到超时),但我不认为将它们关闭几次是个好主意如果可能的话,分钟工作:

答案 3 :(得分:0)

根据定义,HTTP请求是无状态的。正如其他人指出的那样 - 你无法预测IIS何时会回收这个过程。

更好的方法是创建一个用于执行实际工作的Windows服务,以及用于查询进度的HTTPHandler或页面或其他任何内容,并将其返回给客户端。您可以在同一台计算机上安装该服务,然后使用管道或您希望在页面/处理程序与服务之间连接的任何远程处理通道。

答案 4 :(得分:0)

它的价值,

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    for (int i = 0; i < 100; i++)
    {
        context.Response.Write("Hello World " + i + Environment.NewLine);
        System.Threading.Thread.Sleep(500);
        context.Response.Flush();
    }            
}

在客户端:

httpObject.onreadystatechange = function()
{
    // This is called whenever Flush() is called on the server.
    // when readyState = 4, everything is done, but I can check responseText at anytime.
}

工作得很好。

答案 5 :(得分:-2)

从该网站下载源文件

http://www.stonebroom.com/dafiles/6744-code.zip

检查网址〜/ loadpost / stagedloading.aspx。