假设我们有一个任务数组(称为“tasks”),然后将其转换为一个列表(称为“temp”):
var temp = tasks.ToList();
数组元素指向的那些正在运行的任务会发生什么情况?我们是否有两组单独运行的任务(一组在“任务”中,另一组在“临时”中)?或者他们指向相同的任务?
以下代码(取自《Exam Ref 70-483》一书)与我所说的相关(最后三行):
Task<int>[] tasks = new Task<int>[3];
tasks[0] = Task.Run(() => { Thread.Sleep(2000); return 1; });
tasks[1] = Task.Run(() => { Thread.Sleep(1000); return 2; });
tasks[2] = Task.Run(() => { Thread.Sleep(3000); return 3; });
while (tasks.Length > 0) {
int i = Task.WaitAny(tasks);
Task<int> completedTask = tasks[i];
Console.WriteLine(completedTask.Result);
var temp = tasks.ToList();
temp.RemoveAt(i);
tasks = temp.ToArray();
}
更新:我知道最后三行的目的,但不知道它为什么起作用。
[当我们对一系列任务调用 ToList 时]会发生什么?我们有两组分别运行的任务吗?或者他们指向相同的任务?
这实际上是一个好问题,这取决于您调用的源序列ToList
. If temp
是正在运行的任务的集合(如您的情况),那么ToList
只需创建其引用的副本,这意味着您的新列表将指向同一组任务。
然而,如果temp
构成尚未实例化的任务序列(由于延迟执行),那么您将得到new每次致电时都会执行一组任务ToList
。这是一个简单的例子(使用ToArray
,其效果与ToList
):
int count = 0;
var tasks = Enumerable.Range(0, 10).Select(_ =>
Task.Run(() => Interlocked.Increment(ref count)));
// tasks = tasks.ToArray(); // deferred vs. eager execution
Task.WaitAll(tasks.ToArray());
Task.WaitAll(tasks.ToArray());
Console.WriteLine(count);
如果运行上面的代码,最终结果将是20
,这意味着运行了两批任务(每批任务一批)ToArray
称呼)。但是,如果取消注释启用急切执行的行,则最终结果将变为10
,表明后续的ToArray
调用仅复制引用,而不产生新任务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)