Accepted way to prevent “The remote host closed th

2020-02-13 09:28发布

问题:

I'm constantly getting the following exception which is caused by a user initiating a download and it consequently failing (or being cancelled):

Error Message : The remote host closed the connection. The error code is 0x80072746. Stack Trace : at System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.FlushCore(Byte[] status, Byte[] header, Int32 keepConnected, Int32 totalBodySize, Int32 numBodyFragments, IntPtr[] bodyFragments, Int32[] bodyFragmentLengths, Int32 doneWithSession, Int32 finalStatus, Boolean& async) at System.Web.Hosting.ISAPIWorkerRequest.FlushCachedResponse(Boolean isFinal) at System.Web.Hosting.ISAPIWorkerRequest.FlushResponse(Boolean finalFlush) at

I've searched all over the internet, and found an interesting article, however there doesn't seem to be a definitive answer as the best way to prevent this filling up the logs.

The user sees no error and there's no actual problem in the app as it occurs only (to my understanding) in situations out of its control (user cancelling download or loss of connection) but there has to be a way to prevent such an exception being reported.

I hate to say it but I'm tempted to check for this exception and empty catch block its ass away - but this makes me feel like a dirty programmer.

So - what is the accepted method of preventing this exception filling up my mailbox?

回答1:

You cannot prevent a remote Host to close anything.

And in some protocols this is the normal (or at least accepted) way to say goodbye.

So you will have to handle this specific exception.



回答2:

The error occurs when you try to send a response to the client but they have disconnected. You can verify this by setting a breakpoint on the Response.Redirect or wherever you are sending data to the client, wait for Visual Studio to hit the breakpoint, then cancel the request in IE (using the x in the location bar). This should cause the error to occur.

To capture the error you can use the following:

try
{
    Response.Redirect("~/SomePage.aspx");
    Response.End();
}
catch (System.Threading.ThreadAbortException)
{
    // Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex)
{
    if (ex.ErrorCode == unchecked((int)0x80070057)) //Error Code = -2147024809
    {
        // Do nothing. This will happen if browser closes connection.
    }
    else
    {
        throw ex;
    }
}

Or in C# 6 you can use Exception filters to prevent having to re throw the error:

try
{
    Response.Redirect("~/SomePage.aspx");
    Response.End();
}
catch (System.Threading.ThreadAbortException)
{
    // Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex) when (ex.ErrorCode == unchecked((int)0x80070057))
{
    // Do nothing. This will happen if browser closes connection.
}

Which is a better debugging experience since it will stop on the statement throwing the exception with the current state and all local variables preserved instead of on the throw inside the catch block.



回答3:

From a practical perspective, there is nothing wrong with cancelling a download by virtue of a dead computer or a killed web session, therefore catching remote host closed exceptions is perfectly acceptable.