我有一个代理列表,每个代理都会访问各个站点,并从站点中提取所需的数据。目前它一次只做这个。但是我希望一次运行10到20个任务,所以它一次从20个站点下载而不是一个。
以下是我目前的做法:
private async Task<string> DownloadDataFromSite(string url)
{
// (await) Do Work.
return HTMLSourceCode;
}
然后我遍历代理
foreach(Proxy p in proxies)
{
string source = await DownloadDataFromSite(site);
}
Parallel.ForEach
是否适合这样的任务?我已经尝试过,但我现在遇到的问题是无法await
。
答案 0 :(得分:5)
一种方法是避免在foreach中等待。问题是你的await
会有效阻止你的执行。更好的方法可能是这样的:
await Task.WhenAll(proxies.Select(p => DownloadDataFromSite(site)));
这意味着您将立即等待所有任务,这意味着异步I / O将并行发生。请注意,如果您正在进行CPU工作,那么就不会真正实现并行化。
关键是,异步I / O(例如下载网页)不需要更多线程并行运行。另一方面,Parallel.ForEach
实际上是用于CPU绑定工作,而不是I / O绑定工作,它确实在多个线程上执行代码。
答案 1 :(得分:0)
PArallel.ForEach
不能很好地工作,因为它期望同步lambda并给它一个异步lambda基本上会导致它一启动就返回。虽然有一种解决方法,但请查看以下问题:Is it OK to do some async/await inside some .NET Parallel.ForEach() code?