Kam*_*ely 2 .net c# task-parallel-library
假设我们有一系列任务(称为"任务"),然后将其转换为列表(称为"temp"),方法是:
var temp = tasks.ToList();
Run Code Online (Sandbox Code Playgroud)
运行数组元素指向的任务会发生什么?我们是否分别运行两组任务(一组在'tasks'中,另一组在'temp'中)?或者他们指向相同的任务?
以下代码(摘自考试参考文献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();
}
Run Code Online (Sandbox Code Playgroud)
更新:我知道最后三行的目的但不知道它为什么起作用.
当我们在一系列任务上调用ToList时会发生什么?我们是否分别运行两组任务?或者他们指向相同的任务?
这实际上是一个很好的问题,它取决于您调用的源序列ToList
.如果temp
是正在运行的任务的集合(如您的情况),则ToList
只需创建其引用的副本,这意味着您的新列表将指向同一组任务.
但是,如果temp
构成一系列尚未实例化的任务(由于延迟执行),那么每次调用时都会得到一组新的任务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);
Run Code Online (Sandbox Code Playgroud)
如果运行上面的代码,最终结果将是20
,这意味着运行了两批任务(每个ToArray
调用一个).但是,如果取消注释启用执行执行的行,则最终结果将变为10
,表示后续ToArray
调用仅复制引用,而不是生成新任务.
归档时间: |
|
查看次数: |
552 次 |
最近记录: |