2010-09-26 71 views
6

嗨,我有一个函数,通过网址获取参数到一个Web服务器上的PHP文件,并等待文件的响应(通常需要10-20秒)。我想把它放在一个循环中,因为我必须一次将这些Get请求发送给大约5个不同的php文件,但是当我尝试将它添加到循环中时,函数会使循环等待,直到文件返回响应到下一个。使用C#异步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 2010-09-26 18:38:27

回答

9

而不是使用GetResponse()方法,你可以使用非阻塞呼叫BeginGetResponse()。它需要一个回调,它可以在最终返回时处理对象WebResponse。链接中的示例将为您提供有关如何让主线程等待所有响应返回的好主意。

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答案没有错,这个答案会更好地回答这个问题,并且会更容易实现。 – 2010-09-26 21:42:31

+0

+1事实上,ContinueWith()方法是一个好主意 – linuxuser27 2010-09-26 21:45:38

+0

如果我需要用BeginGetRequestStream/EndGetRequestSteam发送HTTP POST请求的数据,这将如何改变?http://stackoverflow.com/questions/4190903 – 2010-11-16 12:01:57