HttpContext抛出HttpException

时间:2011-04-03 22:51:58

标签: c# asp.net .net iis-7 httpexception

我写了一个自定义的http处理程序。我通过编写一个实现IHttphandler的类来完成这个。

在该类中,我有这样的代码,

context.Response.Clear();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Disposition", "attachment;filename=" + attachmentFileName);
context.Response.AddHeader("Content-Length", new FileInfo(downloadFile).Length.ToString());
context.Response.ContentType = GetMimeType(attachmentFileName);
context.Response.TransmitFile(downloadFile);
context.Response.Flush();
context.Response.Close();

偶尔我会收到这样的错误,

Exception HttpException The remote host closed the connection The error code is 0x800703E3

或者这个,

Exception HttpException The remote host closed the connection The error code is 0x80070040

在这两种情况下,堆栈跟踪都是这样,

at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at System.Web.HttpResponse.Flush()

这在生产中发生,如果我回顾过去几天错误发生了23次,总共上述代码被称为497次。

我怀疑这种失败与用户单击链接以多次启动上述代码(这将为他们提供多个下载对话框)有关,然后他们取消了其中一些。话虽如此,如果它是这样的话我会期望连接在两端优雅地关闭。

如何证明此错误的确切原因?我试图像这样Why don't trace listeners log custom handler traffic?启用.NET跟踪但无法使其工作。

我发现虽然我已启用IIS跟踪来记录失败的请求。失败再次发生,并且该日志中没有任何内容。

我可以启用任何其他跟踪吗?

我接下来要做的就是这个,

if (context.Response.IsClientConnected)
{
    context.Response.Flush();
    context.Response.Close();
}
else
{
    LogMessage("Client has disconnected before flush was called", Severity.Information);
}

但这没有任何区别。我猜的原因是客户端在下载过程中断开连接,而不是在调用flush之前。

7 个答案:

答案 0 :(得分:14)

取出Flush()Close()电话。你真的不需要它们。处理程序完成后,它将退出,ASP.NET将处理关闭请求。

此外,当您将内容流式传输到客户端时,应使用Flush()(在块中将部分添加到响应流中)。您无需将其与TransmitFile()一起使用。

答案 1 :(得分:8)

我遇到了类似的问题,得到了这篇文章,它解释了应该避免使用Response.End(),而是建议使用CompleteRequest()方法。 MSDN文档也已使用此信息进行了更新。我希望这有助于某人。

http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx

答案 2 :(得分:4)

使用Response.End()代替Response.Flush()

这就是Response.End()的源代码:

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

答案 3 :(得分:2)

您使用的是什么.NET框架?这个论坛帖子here描述了一个类似的问题,使用IIS7和.NET2.0专门处理客户端断开连接,这是.NET Framework 3.5中解决的一个问题

实际的错误代码映射到

0x800703E3 "The I/O operation has been aborted because of either a thread exit or an application request."

答案 4 :(得分:1)

尝试将Web配置中的max size文件设置为更大的文件。

您可以设置maxRequestLength(以kb为单位)

尝试不经常在iis上重新应用app池。

答案 5 :(得分:1)

有关此例外的详细信息,请访问http://support.microsoft.com/kb/977453

答案 6 :(得分:0)

我有时会遇到错误:

Exception message: An error occurred while communicating with the remote host. The error code is 0x80070057.

随机生产。它不能在开发或质量保证中重现。

我将应用此解决方案:Response.IsClientConnected我希望它能解决错误。

来源:

https://stackoverflow.com/a/11441375/1536197