我希望制作一个可以处理并发下载的框架。我不确定我是否可以使用Task.Run免费获得它?我下面的代码有一个foreach循环,但我真正想要的不是一次一个,而是在他们自己的线程上同时执行5个,然后在完成任务后继续处理移动它进行更多处理。我现在这样做吗?
public async Task ProcessBatch()
{
CreateConnection();
List<string> items=new List<string>();
foreach (var item in items)
{
//do do stuff that possibly takes awhile
var result = await Task.Run(() => DownloadItems());
//do more processing on whatever item is done now
}
}
答案 0 :(得分:3)
您导致Task.Run()
使用不同的主题,但是您导致for
循环到await
该主题的回复在它转移到下一个项目之前,所以你没有得到任何并发性。
另一种方法是首先使用Task.Run()
生成任务列表,然后在创建任务后await
创建任务。
var tasks = new List<Task<DownloadResult>>();
foreach (var item in items)
{
//do do stuff that possibly takes awhile
tasks.Add(Task.Run(() => DownloadItems()));
}
foreach (var task in tasks)
{
var result = await task;
//do more processing on whatever item is done now
}
但是,对于这么简单的事情,我建议使用.AsParallel()
扩展方法作为TPL的一部分。
items.AsParallel()
.Select(item => DownloadItems())
.ForAll(result => AdditionalProcessing(result));
答案 1 :(得分:0)
我是否使用Task.Run创建多线程
我希望制作一个可以处理并发下载的骨架。
将并行与并发区分开来非常重要。并行性是关于多线程的。并发可以通过并行完成,但它也可以通过异步代码完成。
特别是,如果要进行CPU绑定工作,线程非常适合,而异步则优于I / O.由于“下载”强烈暗示I / O,我建议采用异步方法:
DownloadItem
但是,如果Parallel
尚未异步,并且您不想花时间来实现它,那么就采用多线程方法(Task.Run
/ Parallel LINQ或{{1}如果你必须)是UI应用程序的可接受的折衷方案。