1

我目前正在实现一个 HTTP 处理程序,它将从某个 3rd 方获取一些 XML 数据的 POST,然后对其进行一些工作。我将对 XML 进行的处理可能需要一些时间。一旦我从 POST 中取出 XML,就无需在处理数据时保持与客户端的连接打开。由于我无法控制客户端何时超时向我发帖,我只想获取 XML 并释放连接。

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

任何想法将不胜感激。谢谢您的帮助!

4

3 回答 3

2
  1. 将接收到的数据保存到某种永久队列(例如 MSMQ)。
  2. 退出处理程序。
  3. 在另一个应用程序中处理来自队列的数据,例如在 Windows 服务中。

这并不完全是“简单的方法”,但对客户来说安全快捷。

于 2012-11-29T15:53:37.690 回答
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 被删除而调用 stop ,它首先会返回而不注销自身。这让我的过程有更多的时间来完成。如果在第二次调用该方法并将立即标志设置为 true 时,它​​会快速记录问题,然后自行注销。

这可能不是最终的解决方案,但出于我的目的,这将负责在非常罕见的情况发生时提醒我,并且在我处理数据时不会阻止客户端的连接。

于 2012-11-29T19:08:32.363 回答
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 
        } 
}
于 2012-11-29T16:06:54.270 回答