6

Hi i have a function that passes url Get parameters to a php file on a webserver and waits for a response from the file (normally takes 10-20 seconds). I want to put this inside a loop because I have to send these Get requests to about 5 different php files at once but when i try to add it to a loop the function makes the loop wait until the file returns the response before it will go on to the next one.

    public string HttpGet(string URI, string Parameters)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URI + Parameters);

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        StreamReader resStream = new StreamReader(response.GetResponseStream());
          return resStream.ReadToEnd().Trim();
    }

    private void SendCommand()
    {
        for( int i = 0; i <= 4; i++)
        {
            AddRTB(HttpGet(url, paramater));
        }
    }

Is there a way that i could send the all 5 requests at once without waiting for the previous to finish? (i was thinking about threading it but alas i never touched it before is i don't know where to start.)

1
  • 1
    Threading is the way to go for this, though you'll need to wait for all 5 to reply before continuing. Commented Sep 26, 2010 at 18:38

4 Answers 4

9

Instead of using the GetResponse() method you could use the BeginGetResponse() which is a non-blocking call. It takes a callback that can then handle the WebResponse object when it finally returns. The example in the link will give you a good idea of how to have the main thread wait for all the responses to return.

Sign up to request clarification or add additional context in comments.

Comments

9

Here are two approaches which uses the TPL.

The first waits for all the requests to complete before you access any of the results

var runningTasks = new List<Task<string>>();

for (int ii = 0; ii <= 4; ii++)
{
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii);

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                                                    wreq.EndGetResponse, 
                                                    null);
    var taskResult = taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim());
    runningTasks.Add(taskResult);
}

Task.WaitAll(runningTasks.ToArray());
IEnumerable<string> results = runningTasks.Select(tsk => tsk.Result);

and the second does something with each result as it comes in:

for (int ii = 0; ii <= 4; ii++)
{
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii);

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                                                    wreq.EndGetResponse, 
                                                    null);
    taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim())
            .ContinueWith((Task<string> trs) => 
                { 
                    var result = trs.Result;
                    DoSomthingWithTheResult(result);
                });
}

3 Comments

+1. Even if @linuxuser27 answer has nothing wrong, this one answers better to the question and will be much easier to implement.
+1 Indeed it is. The ContinueWith() method is a good idea.
And how would this change if I need to send some data with HTTP POST request with BeginGetRequestStream / EndGetRequestSteam ? stackoverflow.com/questions/4190903
1

Instead of GetResponse use BeginGetResonse method of request class. Sample and documentation can be found at http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx

Comments

0

Use WebClient with Async methods.

Begin\End is more difficult to use.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.