1

我看到这篇文章描述了实现IHttpAsyncHandler.

看这部分:

public class MyAsyncHandler : IHttpAsyncHandler
{
    /// 
    /// The queue holds a list of asynchronous results
    /// with information about registered sessions
    /// 
    public static List<myasyncresult> Queue;


    static MyAsyncHandler()
    {
        // Initialize the queue
        Queue = new List<myasyncresult>();
    }



    public IAsyncResult BeginProcessRequest(HttpContext context, 
                        AsyncCallback cb, object extraData)
    {
        // Fetch the session id from the request
        var sessionId   = context.Request["sessionId"];

        // Check if the session is already registered
        if (Queue.Find(q => q.SessionId == sessionId) != null)
        {
            var index = Queue.IndexOf(Queue.Find(q => q.SessionId == sessionId));

            // The session has already been registered,
            // just refresh the HttpContext and the AsyncCallback
            Queue[index].Context  = context;
            Queue[index].Callback = cb;

            return Queue[index];
        }

        // Create a new AsyncResult that holds the information about the session
        var asyncResult = new MyAsyncResult(context, cb, sessionId);

        // This session has not been registered yet, add it to the queue
        Queue.Add(asyncResult);

        return asyncResult;
    }

    public void EndProcessRequest(IAsyncResult result)
    {
        var rslt  = (MyAsyncResult) result;

        // send the message to the recipient using
        // the recipients HttpContext.Response object
        rslt.Context.Response.Write(rslt.Message);

        // reset the message object
        rslt.Message = string.Empty;
    }


}

这里的异步部分在哪里?我在这里看不到任何BeginXXX方法。

Thread.CurrentThread.IsThreadPoolThread我还在第一行进行了 检查BeginProcessRequest,它向我展示了TRUE.

那么这个例子中的异步部分在哪里呢?

4

1 回答 1

2

当这个处理程序收到一个请求时,它会调用BeginProcessRequest. 它不会阻塞调用线程。

处理完成后,它将调用EndProcessRequest.

这将使您的 asp.net 工作进程线程在处理时可以自由地为其他请求提供服务。调用时EndProcessRequest,您可以将处理后的结果发送回客户端。

这里有很多关于asp.net 如何在异步请求生命周期中管理线程的解释。

在异步页面的生命周期中,上下文仅从 ASP.NET 线程池中的一个线程开始。异步请求启动后,上下文不包含任何线程。当异步请求完成时,执行其完成例程的线程池线程进入上下文。这些可能是发起请求的相同线程,但更有可能是在操作完成时碰巧空闲的任何线程。

如果同一应用程序一次完成多个操作,AspNetSynchronizationContext 将确保它们一次执行一个。它们可以在任何线程上执行,但该线程将具有原始页面的身份和文化。

关于何时使用异步的一些推理:

只有在处理请求时您有其他可用的异步步骤(例如离线数据库调用或您也可以调用异步的长硬盘驱动器读取)时,拥有异步处理程序才有用。要正确执行此操作,您将链接异步方法(即 BeginProcessRequest 将使用相同(或单独)回调调用 FileStream.BeginRead 并进行相应处理。)请参阅此处:http: //msdn.microsoft.com/en-us/library/system.web.ihttpasynchandler.aspx

看看这个关于如何使用异步处理程序的非常详细的解释

要构建一个真正有效的异步处理程序,您必须手动生成一个额外的线程来响应 BeginProcessRequest。构建成功的异步处理程序有三个重要方面。首先,构造一个支持 IAsyncResult 从 BeginProcessRequest 返回的类。然后,生成线程以异步执行您的请求处理。最后,通知 ASP.NET 您已完成对请求的处理并准备好返回响应。

总结一下:如果你没有创建一个处理线程,或者等待很长时间,异步处理程序不会有什么好处。等待时,请求没有与之关联的线程。这使得 asp.net 可以很好地扩展,即使是等待很长时间的任务。

于 2012-06-11T07:58:18.620 回答