2010-09-26 5 views
6

Привет, у меня есть функция, которая передает url. Получает параметры в php-файл на веб-сервере и ждет ответа от файла (обычно занимает 10-20 секунд). Я хочу поместить это внутри цикла, потому что я должен отправить эти запросы Get примерно в 5 разных php-файлов одновременно, но когда я пытаюсь добавить его в цикл, функция заставляет цикл ждать, пока файл не вернет ответ, прежде чем он пойдет на следующий.Асинхронные WebRequests с использованием C#

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

Есть ли способ, которым я мог бы отправить все 5 запросов одновременно, не дожидаясь окончания предыдущего? (я думал о том, чтобы нарезать его, но, к сожалению, я никогда не касался его раньше, я не знаю, с чего начать.)

+1

Резьбонарезной путь чтобы пойти на это, хотя вам нужно подождать, пока все 5 ответят, прежде чем продолжить. – ChrisF

ответ

9

Вместо использования метода GetResponse() вы можете использовать BeginGetResponse(), который является неблокирующим вызовом. Он принимает обратный вызов, который затем может обрабатывать объект WebResponse, когда он, наконец, возвращается. Пример в ссылке даст вам хорошее представление о том, как заставить основной поток ждать возврата всех ответов.

0

Использование WebClient с использованием методов асинхронного ввода.

Begin \ End более сложно использовать.

9

Вот два подхода, которые используют TPL.

Первые ждет все запросы, чтобы завершить, прежде чем получить доступ к любой из результатов

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

и второе что-то делает с каждым результатом, как это происходит в:

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); 
       }); 
} 
+0

+1 Даже если @ linuxuser27 ответ не имеет ничего плохого, этот ответ лучше отвечает на вопрос и будет намного проще реализовать. –

+0

+1 Действительно, это так. Метод 'ContinueWith()' является хорошая идея. – linuxuser27

+0

И как это изменится, если мне нужно будет отправить некоторые данные с HTTP POST-запросом с BeginGetRequestStream/EndGetRequestSteam? http://stackoverflow.com/questions/4190903 –

 Смежные вопросы

  • Нет связанных вопросов^_^