2016-12-25 76 views
3

我有一個Windows控制檯客戶端,睡眠幾分鐘,然後喚醒它從Rest API請求新的更新。該請求生成一個響應,json數據涉及一個對象列表,每個對象由ID,描述,截圖作爲URL從API發送到客戶端。控制檯應用程序需要使用json響應,並且對於每個對象,它都會查找URL並嘗試下載與列表中每個對象關聯的相應圖像。代碼如下表示如何在T#中使用TPL實現異步文件下載#

foreach (var jobject in response) 
{ 
    Console.WriteLine(jobject.id); 
    Console.WriteLine(jobject.description); 
    if (jobject.shotUrl != null) 
    { 
     WebClient webclient = new WebClient(); 
     webclient.DownloadFileAsync(new System.Uri(jobject.shotUrl), "F:\\" + jobject.id + ".jpg"); 
    } 
} 

有時可以有大約500 JSON對象,這意味着500的照片下載...又意味着創建500個Web客戶。我覺得這不是個好主意。

我的問題是:如果我依賴TPL,我可以獲得業績嗎?怎麼做?

+3

你的問題是自相矛盾的。你想要更多*性能*還是你想減少*資源使用*? – zaitsman

+0

請記住,每個端點有一個默認連接限制,在控制檯應用程序中它是2個IIRC。這意味着你將永遠無法同時下載超過2個下載。請參閱:https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit(v=vs.110).aspx – rene

+2

@rene在此問題中有一個答案顯示如何增加併發連接http://stackoverflow.com/questions/26206412/asynchronous-downloading-files-in-c-sharp – Alrehamy

回答

1

使用HttpClient的是併發容易得多,你可以宣佈一個私人的HttpClient的類:

System.Net.Http.HttpClient _client = new System.Net.Http.HttpClient(); 

然後你就可以寫下載文件,並將它們保存到磁盤像這樣的方法:

private async Task DownloadFile(string shortUrl, string destination) 
{ 
    using (var response = await _client.GetStreamAsync(shortUrl)) 
    using (var fileStream = File.Create(destination)) 
    { 
     await response.CopyToAsync(fileStream); 
     await fileStream.FlushAsync(); 
    } 
} 

然後你可以使用它像這樣:

try 
{ 
    await DownloadFile(jobject.shortUrl, "F:\\" + jobject.id + ".jpg"); 
} 
catch (Exception e) 
{ 
    // Do appropriate exception handling 
} 

如果你婉t可以並行下載所有文件,你可以使用Task.WhenAll()

try 
{ 
    var tasks = response.Select(j => DownloadFile(j.shortUrl, "F:\\" + j.id + ".jpg")); 
    await Task.WhenAll(tasks); 
} 
catch (Exception e) 
{ 
    // Do appropriate exception handling 
} 
+1

我對你的代碼進行了基準測試,它的性能現在更糟,我的原始工作 – Alrehamy

+0

說實話,我沒有運行代碼,因爲我沒有足夠的上下文(例如什麼是「響應」)。但我肯定有一點調整異步代碼(特別是Task.WhenAll)將提供更好的性能。 – Encrypt0r

+0

並行下載文件也應該採用'async'方式:'async j =>等待DownloadFile',而不僅僅是'j => DownloadFile',因爲在第二種情況下它是以併發方式同步完成的。 – VMAtm