E
eseaflower
I would like to know if there is a way for a HttpHandler to close a
connection to a client. Specifically to be able to close the
connection after issuing a Write to the client response. I will
examplify below.
Here is a simple handler that does nothing of interest, just sending
100 chunks of 64kB data, it is by no means "production code" just an
example.
/// <summary>
/// Process the incomming requets (relay to the stream
dispatcher.
/// </summary>
public void ProcessRequest(HttpContext context) {
// Check arguments.
if (context == null) {
throw new ArgumentException("Cannot process null http
context.");
}
HttpResponse clientResponse = context.Response;
// Get the stream.
System.IO.Stream outputStream =
clientResponse.OutputStream;
// Disable buffering since the results of streaming
// calls are usually very large and we need the
intermediate
// results.
clientResponse.Buffer = false;
byte[] sendBuffer = new byte[64 * 1024];
for (int i=0;i<100 &&
clientResponse.IsClientConnected;i++) {
outputStream.Write(sendBuffer, 0,
sendBuffer.Length);
}
clientResponse.End();
}
The executing thread will block on the Write statement until the
client reads off the data. If the client does not read off the data
the executing server thread will block, in this case I would like a
mechanism for the HttpHandler to stop processing and close the
connection to the client. Failure to do this will sooner or later
starve the ASP.NET threadpool and block the entire server for further
requests.
To preempt some of the usual suggestions I will explain what I have
tried so far to solve this issue.
1) Make the write asyncronous: (Pseudo example):
IAsyncResult ar = outputStream.BeginWrite(sendBuffer,
0, sendBuffer.Length, null, null);
if (!ar.AsyncWaitHandle.WaitOne(TimeoutMs)) {
// Write timed out, end the request
clientResponse.End();
}
outputStream.EndWrite(ar);
With the above code the processing stops (clientResponse.End() will
abort the thread and stop any processing). However the web server will
still show that the request is executing (checking the state of the
current requests in IIS7) it says that the request is in state
"SendResponse". Once I reach 10 of these requests in state
"SendingResponse" the server will stop responing.
2) Surely the httpRuntime executionTimeout will kick in and abort the
processing? Same result as in 1).
So eventhough I seemingly end the current request in both 1) and 2)
above the request will show up in the IIS7 manager and once we have 10
of these requests queued the server will stop responding.
Anyone have suggestions on how to completely end a client request in a
HttpHandler (including removing any pending Writes etc.)?
Some specs.
OS: Win7
IIS version: 7
..NET Framework version: 2
Managed Pipeline Mode: Classic
connection to a client. Specifically to be able to close the
connection after issuing a Write to the client response. I will
examplify below.
Here is a simple handler that does nothing of interest, just sending
100 chunks of 64kB data, it is by no means "production code" just an
example.
/// <summary>
/// Process the incomming requets (relay to the stream
dispatcher.
/// </summary>
public void ProcessRequest(HttpContext context) {
// Check arguments.
if (context == null) {
throw new ArgumentException("Cannot process null http
context.");
}
HttpResponse clientResponse = context.Response;
// Get the stream.
System.IO.Stream outputStream =
clientResponse.OutputStream;
// Disable buffering since the results of streaming
// calls are usually very large and we need the
intermediate
// results.
clientResponse.Buffer = false;
byte[] sendBuffer = new byte[64 * 1024];
for (int i=0;i<100 &&
clientResponse.IsClientConnected;i++) {
outputStream.Write(sendBuffer, 0,
sendBuffer.Length);
}
clientResponse.End();
}
The executing thread will block on the Write statement until the
client reads off the data. If the client does not read off the data
the executing server thread will block, in this case I would like a
mechanism for the HttpHandler to stop processing and close the
connection to the client. Failure to do this will sooner or later
starve the ASP.NET threadpool and block the entire server for further
requests.
To preempt some of the usual suggestions I will explain what I have
tried so far to solve this issue.
1) Make the write asyncronous: (Pseudo example):
IAsyncResult ar = outputStream.BeginWrite(sendBuffer,
0, sendBuffer.Length, null, null);
if (!ar.AsyncWaitHandle.WaitOne(TimeoutMs)) {
// Write timed out, end the request
clientResponse.End();
}
outputStream.EndWrite(ar);
With the above code the processing stops (clientResponse.End() will
abort the thread and stop any processing). However the web server will
still show that the request is executing (checking the state of the
current requests in IIS7) it says that the request is in state
"SendResponse". Once I reach 10 of these requests in state
"SendingResponse" the server will stop responing.
2) Surely the httpRuntime executionTimeout will kick in and abort the
processing? Same result as in 1).
So eventhough I seemingly end the current request in both 1) and 2)
above the request will show up in the IIS7 manager and once we have 10
of these requests queued the server will stop responding.
Anyone have suggestions on how to completely end a client request in a
HttpHandler (including removing any pending Writes etc.)?
Some specs.
OS: Win7
IIS version: 7
..NET Framework version: 2
Managed Pipeline Mode: Classic