怎么搞定所有任务
Posted
技术标签:
【中文标题】怎么搞定所有任务【英文标题】:How do get all tasks in 【发布时间】:2017-10-07 18:17:30 【问题描述】:我如何获得一个用于Task.WaitAll
的迭代器,以等待customList
中存在的所有任务以最低的开销或代码行数?
public class Custom
public Task task;
public int result;
public class Main
void doSomething()
List<Custom> customList=new List<>();
//customList.Add(custom1,2,3,4,5.....);
Task.WaitAll(????)
【问题讨论】:
Task.WaitAll(customList.Select(c => c.task).ToArray());
?
为什么要将任务存储在类中? Task 不是线程,它代表一个执行。如果您想从任务列表中获取结果,只需使用var results=await Task.WhenAll(myListOfTasks);
。它也无法识别,因此没有理由使用自定义类来“包装”它
@juharr task.waitall 阻塞调用 where task.whenAll 主要不是这个区别
换句话说,正如人们在您之前的问题中已经回答的那样,停止尝试将任务当作线程来使用,或者好像它们需要某种抽象。他们没有。您可以使用带有 var tasks=myUrls.Select(url=>client.GetStringAsync(url));var contents=await Task.WhenAll(tasks)
的单个客户端从 url 列表中获取结果。您可以将 URL 与结果或检查与var tasks=myUrls.Select(url=>var response=client.GetStringAsync(url);return new Url=url;Response=response;)
结合起来
@ColinM OP 在今天的上一个问题中将任务与 Parallel.ForEach 和 async 混淆了。 OP 正在询问如何从多个 URL 并行检索内容
【参考方案1】:
任务不是线程。它们代表函数的执行,因此将它们及其结果存储为类是没有意义的。如果您使用Task.WhenAll
,获取多个任务的结果非常容易。
没有理由将任务包装在一个类中。您可以将 Task 本身视为线程调用的包装器,并且是结果。
如果您想从多个页面检索内容,您可以使用 LINQ 单个 HttpClient 一次从多个页面请求内容。 await Task.WhenAll
将返回所有任务的结果:
string[] myUrls=...;
HttpClient client=new HttpClient();
var tasks=myUrls.Select(url=>client.GetStringAsync(url));
string[] pages=await Task.WhenAll(tasks);
如果你想返回更多数据,例如检查内容,你可以在Select
lambda: 中这样做:
var tasks=myUrls.Select(async url=>
var response=await client.GetStringAsync(url);
return new
Url=url,
IsSensitive=response.Contains("sensitive"),
Response=response
;
);
var results =await Task.WhenAll(tasks);
Results 包含在Select
中生成的匿名对象。您可以像任何其他数组一样迭代或查询它们,例如:
foreach(var result in results)
Console.WriteLine(result.Url);
【讨论】:
以上是关于怎么搞定所有任务的主要内容,如果未能解决你的问题,请参考以下文章