【发布时间】:2016-03-10 23:42:49
【问题描述】:
我在 C# 异步方面没有太多经验。
任务 - 从 Internet 加载位图。以前,我只是一个一个地同步加载它们。异步加载它们会更快地产生结果。在下面,我做了两个例子,我如何获得单个图像 - GetImage 和 GetImageAsync。对于图像列表,我会使用LoadImages 和LoadImages2。
LoadImages 将以异步方式运行同步函数(所有同时 (?)),LoadImages2 将以异步方式运行异步函数并产生相同的结果 (?)。
那件事,我不完全理解 - 在GetImageAsyncawait request.GetResponseAsync()。我真的需要吗?这是做同样事情的“更好”方式吗? LoadImages 和 LoadImages2 之间真的有什么区别吗?
目前,我正在考虑选择GetImage 和LoadImages 选项。另外,我不想用async Task装饰每个函数,我只需要异步加载这些图像。
public Bitmap GetImage(string url)
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (WebResponse response = request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
return new Bitmap(responseStream);
}
public async Task<Bitmap> GetImageAsync(string url)
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (WebResponse response = await request.GetResponseAsync())
using (Stream responseStream = response.GetResponseStream())
return new Bitmap(responseStream);
}
private Dictionary<string, Bitmap> LoadImages(List<string> urls)
{
Dictionary<string, Bitmap> images = new Dictionary<string, Bitmap>();
Task.WaitAll(urls.Select(url =>
Task.Run(() =>
{
images.Add(url, GetImage(url));
})).ToArray());
return images;
}
private Dictionary<string, Bitmap> LoadImages2(List<string> urls)
{
Dictionary<string, Bitmap> images = new Dictionary<string, Bitmap>();
Task.WhenAll(urls.Select(url =>
Task.Run(async () =>
{
images.Add(url, await GetImageAsync(url));
})));
return images;
}
【问题讨论】:
-
LoadImages2看起来像是在填充图像之前返回,因为Task.WhenAll没有等待,而是返回一个等待的Task -
好的,应该是
await Task.WhenAll(...),对吧?但我不能在同步功能中使用await。那么Task.WhenAll(...).RunSynchronously()?这些东西在很多地方都让我的心弯曲。无论如何,我的主要问题是 - 每个图像加载都需要一项任务吗?我已经在LoadImages中将它们作为任务运行。那么有区别吗? -
您不能在没有
async的情况下使用await。一般来说,如果你启动它,建议一直异步 -> 你异步加载图像?那么你的LoadImages方法应该是异步的,除非你达到了异步不再是一个选项的地步。
标签: c# async-await