我想知道为什么从已经完成的任务中获得结果需要这么长时间。List<Task<T>> myTasks = someList.Select(x => Task.Run(() => DoSomethingWith(x)));Task.WaitAll(myTasks.ToArray());var myResults = myTasks.Select(task => task.Result); // the line that takes too long对这些单行进行计时表明,最后一行花费了大量时间(10 个任务超过 25 毫秒)。在我看来,得到结果应该是几乎瞬间的事情,因为结果应该在那个时候已经存在。在这种情况下有没有更好的方法来获得结果?
2 回答
HUH函数
TA贡献1836条经验 获得超4个赞
我会在你更新你的问题时更新这个,但这是我最好的猜测。
这一行不会编译,因为 Select 不返回列表:
List<Task<T>> myTasks = someList.Select(x => Task.Run(() => DoSomethingWith(x)));
我要冒险猜测你实际上正在这样做:
var myTasks = someList.Select(x => Task.Run(() => DoSomethingWith(x)));
...这会产生一个冷IEnumerable
:一个只会在它实际被迭代时运行。
在上面的代码中,当您调用它时,您正在对其进行迭代.ToArray()
。但是你描述为 25ms 的那条线同样只产生了另一种感冒IEnumerable<>
。这里没有做真正的工作:
var myResults = myTasks.Select(task => task.Result);
所以我再次冒险猜测你正在做更多这样的事情:
var myResults = myTasks.Select(task => task.Result).ToList();
...这将重复myTasks
第二次,导致Task.Run(...)
为 中的每个项目再次调用someList
,然后等待所有这些任务完成。
换句话说,你做了两次工作,其中一次在你最后引用的行中。
幸运的是,有一种更好的方法来完成您正在做的事情,那就是使用任务并行库。
var myResults = someList .AsParallel() .Select(x => DoSomethingWith(x)) .ToList();
蝴蝶刀刀
TA贡献1801条经验 获得超8个赞
如果您确定第 3 行是导致减速的那一行,那么就没什么可做的了。这是所有运行时库代码,MS 在优化方面运行得非常严格。
您可能希望手动迭代 myTasks 以避免 Select 代码,但如果您获得了几毫秒,我会感到惊讶。
- 2 回答
- 0 关注
- 253 浏览
添加回答
举报
0/150
提交
取消