我有一个Windows控制台客户端,它可以睡几分钟,然后在唤醒它时会从Rest API请求新的更新。请求生成响应,json数据涉及对象列表,每个对象由ID,描述,屏幕截图从API发送到客户端作为URL。控制台应用程序需要使用json响应,并且对于每个对象,它会查找URL并尝试下载与列表中每个对象关联的相应图像。代码表示如下
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个webclients。我觉得这不是个好主意。
我的问题是:如果我依赖TPL,我可以获得表现吗?该怎么做?
答案 0 :(得分: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
}
如果你想并行下载所有文件,你可以使用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
}