65.9K
CodeProject 正在变化。 阅读更多。
Home

如何从 Web 客户端执行长时间运行的任务(使用 ASP.NET 1.1 和 2.0)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.32/5 (7投票s)

2007年12月14日

CPOL

2分钟阅读

viewsIcon

36060

downloadIcon

262

一种有用的方法是从客户端调用耗时的后端进程/存储过程调用。

引言

Web 应用程序用户经常向开发人员报告,他们在等待进程完成时遇到超时问题。 此进程可能是后端 Web 服务调用、存储过程调用、远程进程调用等。 因此,很明显,它们的执行时间会有所不同,并且相应地增加客户端超时设置不是一个明智的决定。 解决此问题的方法是客户端回调,它不仅可以解决超时问题,还可以告知用户进程的当前状态。

使用代码

实现 IHttpAsyncHandler 以执行 AsyncCallback。 为此,将一个 .ashx 文件添加到您的项目中,并在您的 Web 处理程序类中继承 IHttpAsyncHandlerIRequiresSessionState(在我的示例中,它是 AsyncTaskHandler)。 为了启动对 HTTP 事件处理程序的异步调用,请重写 Web 处理程序类中的“IAsyncResult IHttpAsyncHandler.BeginProcessRequest(...)”和“void EndProcessRequest(...)”。

public IAsyncResult BeginProcessRequest(HttpContext context, 
                    System.AsyncCallback cb, object extraData)
{
    // Get the current Cycle
    object data = context.Request["ProcessNo"];

    // Create a result object to be used by ASP.NET
    AsyncRequestResult result = new AsyncRequestResult(context, cb, data);

    // Create a new request object to perform the main logic
    AsyncRequest request = new AsyncRequest(result);

    // Create a new worker thread to perform the work
    // Notice that this will not remove a thread from the CLR ThreadPool.
    ThreadStart start = new ThreadStart(request.Process);
    Thread workerThread = new Thread(start);

    // Start the work
    workerThread.Start();

    // Return the AsynResult to ASP.NET
    return result;
}

请记住代码的可重用性和面向对象编程的概念。 创建一个类文件作为 AsyncRequest,它将处理 Web 请求,并创建另一个类文件作为 AsyncRequestResult 来管理响应。 进程调用将使用 JavaScript 从客户端启动。 JavaScript 将使用“Microsoft.XMLHTTP”调用 .ashx

function postRequest( url )
{
    var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                    
    // 'true' specifies that it's a async call
    xmlhttp.Open("POST", url, true);
                    
    // Register a callback for the call
    xmlhttp.onreadystatechange = 
    function ()
    {
        if (xmlhttp.readyState == 4)
        {                        
        var response = xmlhttp.responseText;
        document.getElementById('lblMessage').innerHTML = response;
        stopProgressBar();                                                    
        }
    }
                    
    // Send the actual request
    xmlhttp.Send();
}

在 ASP.NET 2.0 中,客户端回调可以更容易地实现,尽管它仍然在内部使用 XMLHTTP。 客户端回调功能实际上包含两部分:ICallbackEventHandler 接口和 Page.GetCallbackEventReference 方法。 架构归结为以下基本步骤。 Page.GetCallbackEventReference 方法及其重载将创建需要在客户端放置的 JavaScript 代码片段。 这些代码片段包含发送 HTTP 请求回页面的代码(在底层使用 XMLHTTP 对象)。 然后,服务器端通过实现 ICallbackEventHandler 接口的 Web 控件处理该请求。 在大多数情况下,该 Web 控件是页面本身,但您可以拥有对请求做出反应的特定用户控件或 Web 控件。 一旦请求被处理,结果就会通过另一个 JavaScript 函数传递回客户端,该函数的唯一目的是对请求的结果做出反应。

© . All rights reserved.