12

I have a HttpHandler that I'm using to handle certain images on a client's website. When I'm outputting the image stream to the response object and call Flush occasionally an error is thrown. Here is a codeblock


var image = Image.FromStream(memStream);
if (size > -1) image = ImageResize.ResizeImage(image, size, size, false);
if (height > -1) image = ImageResize.Crop(image, size, height, ImageResize.AnchorPosition.Center);

context.Response.Clear();
context.Response.ContentType = contentType;
context.Response.BufferOutput = true;

image.Save(context.Response.OutputStream, ImageFormat.Jpeg);

context.Response.Flush();
context.Response.End();

From what I've read, this exception is caused by a client disconnecting before the process has completed and there is nothing to flush.

Here is an output of my error page


System.Web.HttpException: An error occurred while communicating with the remote host. The error code is 0x80070057.
Generated: Mon, 12 Oct 2009 03:18:24 GMT

System.Web.HttpException: An error occurred while communicating with the remote host. The error code is 0x80070057.
   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 System.Web.HttpResponse.Flush(Boolean finalFlush)
   at System.Web.HttpResponse.Flush()
   at PineBluff.Core.ImageHandler.ProcessRequest(HttpContext context) in c:\TeamCity\buildAgent\work\79b3c57a060ff42d\src\PineBluff.Core\ImageHandler.cs:line 75
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

context.Response.Flush falls at line 75.

Is there a way to check this before performing the flush without wrapping it in a try/catch block.?

Anthony Shaw
  • 8,146
  • 4
  • 44
  • 62

4 Answers4

11

Personally in your implementation since the next line is Response.End(), just remove the call to Response.Flush() as Response.End() takes care of everything for you.

Mitchel Sellers
  • 62,228
  • 14
  • 110
  • 173
7

While I agree with Mitchel - there's little need to call flush as you're about to call End, if you're using this elsewhere, you could try calling Response.IsClientConnnected first.

Gets a value indicating whether the client is still connected to the server.

Community
  • 1
  • 1
Zhaph - Ben Duguid
  • 26,785
  • 5
  • 80
  • 117
  • so, could I wrap my .Flush() and .End() in a .IsClientConnected and have that fix my issue do you think? The client's customers do not receive the error on their screens, I just get emails from ELMAH each time. Just a minor annoyance more than anything. – Anthony Shaw Oct 12 '09 at 18:42
  • You could certainly wrap the .Flush in the check - not too sure about any repercussions of not calling .End... I assume there's some long running process in there that's causing people to disconnect before you've finished generating the image? – Zhaph - Ben Duguid Oct 12 '09 at 20:58
  • I can confirm that wrapping flush inside a .IsClientConnected can throw the same exception; happened to me right now. Sticking with .End() – Contra Jun 28 '11 at 09:02
0

I realise this is an old post but it came up when I was looking for an answer to a similar issue. The following is largely verbatim from this SO answer. More background info is available at Is Response.End() considered harmful?.

Replace this: HttpContext.Current.Response.End();

With this:

HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
Community
  • 1
  • 1
David Clarke
  • 12,888
  • 9
  • 86
  • 116
0

For future readers..

I ran into this case where Response.End() throws an error because the client is disconnected.

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

Oddly a CRLF in the StatusDescription was causing the connection to close.

Response.StatusDescription = ex.Message;

Cannot insert the value NULL into column '', table ''; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated

Removing it fixed my problem.

Response.StatusDescription = ex.Message.Replace("\r\n", " ");
Garfield
  • 1,192
  • 3
  • 12
  • 22