views:

2965

answers:

3

In an ASP.Net application, I need to send some data (urlEncodedUserInput) via http POST to an external server in response to user input, without holding up the page response. It doesn't matter what the response from the other server is, and I don't care if the request fails sometimes. This seems to be operating fine (see below) but I'm concerned that it's tying up resources in the background waiting for a response that will never be used.

Here's the code:

httpRequest = WebRequest.Create(externalServerUrl);

httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

bytedata = Encoding.UTF8.GetBytes(urlEncodedUserInput);
httpRequest.ContentLength = bytedata.Length;

requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytedata, 0, bytedata.Length);
requestStream.Close();

Pretty standard stuff, but usually at this point you would call httpRequest.getResponse() or httpRequest.beginGetResponse() if you wanted to receive the response asynchronously, but this doesn't seem to be necessary in my scenario.

Am I doing the right thing? Should I call httpRequest.Abort() to clean up or could this prevent the request from being sent on a slow connection?

+3  A: 

I think Threadpool.QueueUserWorkItem is what you're looking for. With the addition of lambdas and anonymous types, this can be really simple:

var request = new { url = externalServerUrl, input = urlEncodedUserInput };
ThreadPool.QueueUserWorkItem(
    (data) =>
    {
         httpRequest = WebRequest.Create(data.url);

         httpRequest.Method = "POST";
         httpRequest.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

         bytedata = Encoding.UTF8.GetBytes(data.input);
         httpRequest.ContentLength = bytedata.Length;

         requestStream = httpRequest.GetRequestStream();
         requestStream.Write(bytedata, 0, bytedata.Length);
         requestStream.Close();
         //and so on
     }, request);
Adam Lassek
A: 

Ah of course. I wasn't thinking about threading. That will certainly satisfy my objective of sending a response to the client quickly, but won't the new thread be tied up until a response has been received as well? I'm still interested to know if there's a safe time to Abort a HttpWebRequest after the request is sent but before the response is received. Maybe I'm just showing my lack of understanding of the underlying protocols here.

Stuart Matheson
The thread can take as long as it likes without interfering with the main site, but yes, it will be tied up until the response comes back. I don't know of a way to disregard the response like you're thinking.
Adam Lassek
A: 

The only way I can think of that you would get a quick response from the other request is to have the page you're posting to open a thread using the ThreadPool.QueueUserWorkItem so that the main thread finishes the response before the time consuming work is complete. You should know that once the main thread exits you will not have access to the HttpContext which means no caching, server variables, etc... also shared drives will not work unless you Impersonate a user with permissions in the new thread. Threads are nice, but there are a lot of things to look out for.