2014-02-27 55 views
2

我想使用C#中的任務同時從網站下載一些圖片。當調用WaitAll()時,應用程序掛起。這裏是我的代碼:使用異步任務下載圖像

HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 }; 

List<Task<byte[]>> tasks = new List<Task<byte[]>>(); 

for (int i = 0; i < 10; i++) 
     { 
      string url = string.Format("http://www.myurl.com/files//53/{0}page.jpg",i); 
      Task<byte[]> download = ProcessURLAsync(url, client); 
      tasks.Add(download); 
     } 

Task.WaitAll(tasks.ToArray()); 

和方法ProcessURLAsync:

async Task<byte[]> ProcessURLAsync(string url, HttpClient client) 
    { 
     var byteArray = await client.GetByteArrayAsync(url); 
     return byteArray; 
    } 

回答

4

使用await Task.WhenAll(tasks);由於Task.WaitAll會阻止調用線程。

在附註中,您可以使用相同的HttpClient實例:)它專爲多個併發請求而設計。請參閱http://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx的註釋部分

+0

您*可以*共享一個實例,但每個實例都會擁有自己的連接池,這可能會限制您的吞吐量。這裏的整點是爲了避免這一點,並同時下載。 –

+0

@ReedCopsey對不起'可能油門'沒有對我說什麼。是否這樣做?我自己的經歷並不像你說的那樣表現出任何東西。 – EZI

+0

這取決於您一次嘗試執行多少個連接。只有連接池允許單個實例下載的次數纔會成功。 –

2

而不是使用Task.WaitAll的,你應該使用await Task.WhenAll。這將異步等待任務完成。 Task.WaitAll阻止設計,直到任務完成。

在附註中,每個請求應該使用它自己的HttpClient實例。

+0

我認爲只有在您可以測量單個實例爲瓶頸並且衡量變化有所不同時,纔會使用多個「HttpClient」實例進行性能優化。 – Anupam