C#:为什么在任务已经完成的情况下,获取 Task t.Result 需要这么长时间?

我想知道为什么从已经完成的任务中获得结果需要这么长时间。


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 毫秒)。在我看来,得到结果应该是几乎瞬间的事情,因为结果应该在那个时候已经存在。在这种情况下有没有更好的方法来获得结果?


慕村225694
浏览 255回答 2
2回答

HUH函数

我会在你更新你的问题时更新这个,但这是我最好的猜测。这一行不会编译,因为 Select 不返回列表:List<Task<T>>&nbsp;myTasks&nbsp;=&nbsp;someList.Select(x&nbsp;=>&nbsp;Task.Run(()&nbsp;=>&nbsp;DoSomethingWith(x)));我要冒险猜测你实际上正在这样做:var&nbsp;myTasks&nbsp;=&nbsp;someList.Select(x&nbsp;=>&nbsp;Task.Run(()&nbsp;=>&nbsp;DoSomethingWith(x)));...这会产生一个冷IEnumerable:一个只会在它实际被迭代时运行。在上面的代码中,当您调用它时,您正在对其进行迭代.ToArray()。但是你描述为 25ms 的那条线同样只产生了另一种感冒IEnumerable<>。这里没有做真正的工作:var&nbsp;myResults&nbsp;=&nbsp;myTasks.Select(task&nbsp;=>&nbsp;task.Result);所以我再次冒险猜测你正在做更多这样的事情:var&nbsp;myResults&nbsp;=&nbsp;myTasks.Select(task&nbsp;=>&nbsp;task.Result).ToList();...这将重复myTasks&nbsp;第二次,导致Task.Run(...)为 中的每个项目再次调用someList,然后等待所有这些任务完成。换句话说,你做了两次工作,其中一次在你最后引用的行中。幸运的是,有一种更好的方法来完成您正在做的事情,那就是使用任务并行库。var&nbsp;myResults&nbsp;=&nbsp;someList &nbsp;&nbsp;&nbsp;&nbsp;.AsParallel() &nbsp;&nbsp;&nbsp;&nbsp;.Select(x&nbsp;=>&nbsp;DoSomethingWith(x)) &nbsp;&nbsp;&nbsp;&nbsp;.ToList();

蝴蝶刀刀

如果您确定第 3 行是导致减速的那一行,那么就没什么可做的了。这是所有运行时库代码,MS 在优化方面运行得非常严格。您可能希望手动迭代 myTasks 以避免 Select 代码,但如果您获得了几毫秒,我会感到惊讶。
打开App,查看更多内容
随时随地看视频慕课网APP