我已经编写了一个自定义的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之前。
发布于 2011-05-25 10:42:58
去掉Flush()
和Close()
调用。你真的不需要他们。一旦您的处理程序完成,它将退出,并且ASP.NET将处理关闭请求。
此外,当您将内容流式传输到客户端(以块为单位向响应流添加部分)时,应该使用Flush()
。您不需要在TransmitFile()
中使用它。
发布于 2012-03-07 05:40:28
我也遇到过类似的问题,我得到了这篇文章,它解释了应该避免使用Response.End()方法,并建议使用CompleteRequest()方法。MSDN文档也已根据此信息进行了更新。我希望这对某些人有帮助。
发布于 2011-04-04 11:07:30
使用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();
}
}
}
https://stackoverflow.com/questions/5533068
复制相似问题