ASP.net HttpHandler 长时间运行的 ProcessRequest 不会在应用程序回收时结束

2024-02-10

我正在尝试在 ASP.net 中实现 HttpStreaming comet 推送服务器。我正在实现一个 IHttpAsyncHandler,它保存 http 请求并定期向连接的客户端发送消息。与客户端的连接可以保持打开很长一段时间(假设 30 分钟)。我遇到的问题是,由于我很长时间没有结束请求,因此处理程序技术仍在运行。因此,当应用程序池回收或结束时,我的 asp.net 应用程序不会正常结束。这意味着,Application_End 永远不会在 Global.asax 中被调用,因为它在被调用之前等待所有处理程序完成。我的处理程序尚未完成,因为它正在保留该请求。最终,应用程序被 IIS 杀死。

这里有一个示例 HttpHandler,它会无限运行,直到有消息告诉它停止为止。

public class StreamingSocketHandler3 : IHttpHandler
{
    private static readonly AppDomainShutdown Instance = AppDomainShutdown.Instance;

    public void ProcessRequest(HttpContext context)
    {

        long c = 1;
        bool stop = false;
        Instance.OnStop += delegate()
        {
            stop = true;
        };

        while (!stop)
        {
            LogThis.Log.LogThis("loop: " + c, LogThis.eloglevel.debug);
            c++;
            System.Threading.Thread.Sleep(1000);
        }
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }
}

如果客户端连接到此处理程序,然后我停止应用程序池,则 Web 应用程序不会结束,直到该应用程序稍后被 IIS 完全终止。

这个问题的明显答案是监听某种应用程序结束事件,然后结束请求。我无法连接到 Global.asax Application_end,因为它在处理程序结束之前不会被调用。以下博文(link http://blogs.msdn.com/b/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx)提供了一些其他替代方案(请参阅帖子末尾的 q5)。我尝试过 AppDomain.DomainUnload 事件建议,但没有成功。我还尝试了建议的 IRegisteredObject 接口。那也行不通。我构建了以下实现 IRegisteredObject 的类以进行测试。

public sealed class AppDomainShutdown : IRegisteredObject
{
    public event Action OnStop;

    // Singleton reference
    public static readonly AppDomainShutdown Instance = new AppDomainShutdown();

    // Singleton private Constructor
    private AppDomainShutdown()
    {
        // Register the object
        HostingEnvironment.RegisterObject(this);
    }

    public void Stop(bool immediate)
    {
        // Whats it want us to do?
        if (!immediate)
        {
            // Do some code to handle graceful
            // if OK
            LogThis.Log.LogThis("Not Immediate Stop called", LogThis.eloglevel.debug);
            OnStop();
            HostingEnvironment.UnregisterObject(this);
        }
        else
        {
            // Do some code to force down (THREAD.ABORT)
            // Mandatory
            LogThis.Log.LogThis("Immediate Stop called", LogThis.eloglevel.debug);
            OnStop();
            HostingEnvironment.UnregisterObject(this);
        }
    }
}

如果我在没有启动处理程序的情况下从 Global.asax 调用此类,我会按预期收到应用程序停止通知。但是,在 HttpHandler 中放置相同的调用(请参阅处理程序代码),OnStop 事件永远不会触发。

令人沮丧的是,我在网络上看到了一些论坛帖子,这些帖子有我的确切问题,并且发布者据说能够实现 IRegisteredObject 并结束 HttpRequest,以便应用程序可以关闭。

请注意,我提供的 HttpHandler 代码只是为了测试我是否可以结束 ProcessRequest 方法以响应应用程序结束。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.net HttpHandler 长时间运行的 ProcessRequest 不会在应用程序回收时结束 的相关文章

随机推荐