在.NET HTTPHandler中释放连接

时间:2012-11-29 15:47:03

标签: c# asp.net .net

我目前正在实现一个HTTP处理程序,它将从某些第三方获取一些XML数据的POST,然后将使用它做一些工作。我将使用XML进行的处理可能需要一些时间。一旦我从POST中抽出XML,就不需要在处理数据时保持与客户端的连接打开。因为我无法控制客户端何时会向我发布时间,所以我只想获取XML并继续连接。

有没有简单的方法可以解决这个问题?使用Response.Close()是不正确的,因为它没有正确关闭连接。 Response.End()一起退出我的HTTP处理程序。我可以把处理放到后台线程中,但我听说在ASP.NET中有点风险,因为AppDomain可以被拆除,这可能会在中间杀死我的进程。

任何想法都会非常感激。谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

  1. 将收到的数据保存到某种永久队列(例如MSMQ)。
  2. 退出处理程序。
  3. 从另一个应用程序中的队列处理数据,例如在windows服务中。
  4. 这不是“简单的方法”,而是对客户安全而快速。

答案 1 :(得分:1)

感谢大家的意见。我这样做的方式,以便其他人可以将其作为解决方案进行思考:

排队可能是最“正确”的方法,但是需要一些额外的实现才能真正实现我想要做的事情。使用http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

中的信息

首先,我创建了我的处理类,并在后台线程中将其旋转,以便在从客户端获取XML之后完成工作。这会在我的工作线程在后台继续时释放连接。

我将处理类注册为IRegisteredObject。我实现了Stop(bool immediate)方法

    public void Stop(bool immediate)
    {
        if (!immediate && _working)
            return;//don't unregister yet, give it some time

        if(immediate && _working)
        {
            //TODO: Log this instance
        }
        HostingEnvironment.UnregisterObject(this);
    }

我在处理工作时将我的_working变量设置为true,并在完成后取消设置。如果在极少数情况下我正在处理工作并因为AppDomain被取消而停止调用,它将首先返回而不取消注册本身。这使我的过程有更多的时间来完成。如果第二次调用该方法并将immediate标志设置为true,它会快速记录该问题,然后取消注册。

这可能不是最终解决方案,但就我的目的而言,这将在非常罕见的情况发生时提醒我,以及在我处理数据时不会阻止客户端的连接。

答案 2 :(得分:0)

如果您使用的是.NET 4.5,请查看HttpTaskAsyncHandler

从链接页面:

  

异步HTTP处理程序在ASP.NET中编写异步处理程序的传统方法是实现IHttpAsyncHandler   接口。 ASP.NET 4.5引入了HttpTaskAsyncHandler   您可以从中派生出来的异步基类型,这样做很多   更容易编写异步处理程序。 HttpTaskAsyncHandler类型   是抽象的,需要您覆盖ProcessRequestAsync   方法。 ASP.NET内部负责集成返回   ProcessRequestAsync的签名(Task对象)与旧版本   ASP.NET管道使用的异步编程模型。该   以下示例显示了如何使用Task和await作为其中的一部分   异步HTTP处理程序的实现:

public class MyAsyncHandler : HttpTaskAsyncHandler 
{ 
        // ... 

        // ASP.NET automatically takes care of integrating the Task based override 
        // with the ASP.NET pipeline. 
        public override async Task ProcessRequestAsync(HttpContext context) 
        { 
           WebClient wc = new WebClient(); 
           var result = await  
                   wc.DownloadStringTaskAsync("http://www.microsoft.com"); 
           // Do something with the result 
        } 
}