2012-10-31 144 views
1

我有一个应用程序使用backgroundWorker向last.fm网站发出API请求。起初我不知道我需要做多少请求。该响应包含页面的总数,所以我只会在第一次请求后才能得到它。这是下面的代码。并行http请求

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    {    
     int page = 1; 
     int totalpages = 1; 

     while (page <= totalpages) 
     { 
      if (backgroundWorker.CancellationPending) 
      { 
       e.Cancel = true; 
       return; 
      } 

      //Here is the request part 
      string Response = RecentTracksRequest(username, from, page); 

      if (Response.Contains("lfm status=\"ok")) 
      { 
       totalpages = Convert.ToInt32(Regex.Match(Response, @"totalPages=.(\d+)").Groups[1].Value); 

       MatchCollection match = Regex.Matches(Response, "<track>((.|\n)*?)</track>"); 
       foreach (Match m in match) 
        ParseTrack(m.Groups[1].Value); 
      } 
      else 
      { 
       MessageBox.Show("Error sending the request.", "Error", 
        MessageBoxButtons.OK, MessageBoxIcon.Error); 
       return; 
      } 

      if (page >= totalpages) 
       break; 

      if (totalpages == 0) 
       break; 

      if (page < totalpages) 
       page++; 
     } 

的问题是last.fm API实在是太慢了,它可能需要长达5秒得到回应。如果页面数量很多,加载将需要很长时间。

我想进行并行请求,一次说3个并行请求。可能吗?如果是的话,我该怎么做?

非常感谢。

+0

顺便说一句,如果您向sa我主持(您的情况是last.fm).NET将限制并发http请求的数量。请参阅此处接受的答案:http://stackoverflow.com/questions/1361771/max-number-of-concurrent-httpwebrequests – Dmitry

回答

7

你可以采取的HttpClient优势,假设你有URL列表:

var client = new HttpClient(); 
var tasks = urls.Select(url => client.GetAsync(url).ContinueWith(t => 
      { 
       var response = t.Result; 
       response.EnsureSuccessStatusCode(); 

       //Do something more 
      })); 

如果使用异步方法,你可以等待所有任务完成如下:

var results = await Task.WhenAll(tasks); 
+0

“Parallel.ForEach”的另一种方法 –

1

你可以做异步的Web请求以及使用BeginGetResponse

 HttpWebRequest webRequest; 
     webRequest.BeginGetResponse(new AsyncCallback(callbackfunc), null); 


     void callbackfunc(IAsyncResult response) 
     { 
     webRequest.EndGetResponse(response); 
     }