20

我写了一个自定义的 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 次上述代码。

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

How can I prove the exact cause of this error? I have tried to enable .NET tracing like this Why don't trace listeners log custom handler traffic? but couldn't get it to work.

What I found though is that I have enabled IIS tracing to log failed requests. The failure occurred again, and NOTHING was in that log.

Any other tracing I can enable for instance?

The next thing I tried was this,

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

But that didn't make any difference. The reason though I guess is that the client disconnected while the download was taking place, not before flush was called.

4

7 回答 7

14

Take out both the Flush() and Close() call. You really don't need them. Once your handler is done, it'll exit, and ASP.NET will handle closing the request.

Besides, Flush() should be used when you're streaming content to the client (adding parts to the response stream in blocks). You don't need to use it with TransmitFile().

于 2011-05-25T02:42:58.123 回答
8

I was into similar issues, got this article which explains that Response.End() should be avoid ed and instead suggests to use CompleteRequest() method. MSDN documentation has also been updated with this information. I hope this helps someone.

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

于 2012-03-06T21:40:28.437 回答
4

Use Response.End() instead of Response.Flush()

This is what the source code for Response.End() looks like:

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();
        }
    }
}
于 2011-04-04T03:07:29.953 回答
2

What .NET framework are you using? This forum thread here describes a similar problem using IIS7 with .NET2.0 specifically to do with the client disconnect, a problem which was addressed in .NET framework 3.5

The actual error code maps to

0x800703E3 "The I/O operation has been aborted because of either a thread exit or an application request."
于 2011-04-03T23:02:02.003 回答
1

try to set up the max size file on the web config to a bigger one.

You can set the maxRequestLength (in kb)

try to not reclycle app pools on iis to often also.

于 2011-04-04T01:25:21.613 回答
1

For more details about this exception visit http://support.microsoft.com/kb/977453

于 2012-01-10T10:03:20.607 回答
0

I have the error sometimes:

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

Is random in production. Its not reproduce in Development or QA.

I will apply this solution: Response.IsClientConnected I hope it will fix the error.

Source:

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

于 2018-05-22T19:33:34.070 回答