How to send http request in asp.net without waitin

2019-02-03 13:00发布

问题:

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?

回答1:

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);


回答2:

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.