Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# tasks.ToList()是否创建包含新复制任务的列表,或者该列表引用相同的任务?_C#_.net_Task Parallel Library - Fatal编程技术网

C# tasks.ToList()是否创建包含新复制任务的列表,或者该列表引用相同的任务?

C# tasks.ToList()是否创建包含新复制任务的列表,或者该列表引用相同的任务?,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,假设我们有一个任务数组(称为“任务”),然后将其转换为一个列表(称为“临时”),方法是: var temp = tasks.ToList(); 数组元素指向的那些正在运行的任务会发生什么情况?我们是否有两组任务分别运行(一组在“任务”中,另一组在“临时”中)?或者他们指向相同的任务 以下代码(摘自考试参考文献70-483)与我所说的内容相关(最后三行): Task[]tasks=新任务[3]; tasks[0]=Task.Run(()=>{Thread.Sleep(2000);返回1;});

假设我们有一个任务数组(称为“任务”),然后将其转换为一个列表(称为“临时”),方法是:

var temp = tasks.ToList();
数组元素指向的那些正在运行的任务会发生什么情况?我们是否有两组任务分别运行(一组在“任务”中,另一组在“临时”中)?或者他们指向相同的任务

以下代码(摘自考试参考文献70-483)与我所说的内容相关(最后三行):

Task[]tasks=新任务[3];
tasks[0]=Task.Run(()=>{Thread.Sleep(2000);返回1;});
tasks[1]=Task.Run(()=>{Thread.Sleep(1000);返回2;});
tasks[2]=Task.Run(()=>{Thread.Sleep(3000);返回3;});
而(tasks.Length>0){
int i=Task.WaitAny(任务);
Task completedTask=任务[i];
Console.WriteLine(completedTask.Result);
var temp=tasks.ToList();
移除温度(i);
tasks=临时ToArray();
}

更新:我知道最后三行的用途,但不知道它为什么起作用。

ToList
创建一个包含IEnumerable项的新列表。它不创建这些项的深度副本,只复制引用。因此,只有一组任务

这些行可能存在,因此开发人员可以使用
RemoveAt
使用索引(从
Task.WaitAny
返回的索引)轻松删除项目

[当我们调用一系列任务的ToList]时,会发生什么?我们是否有两组任务分别运行?或者他们指向相同的任务

这实际上是一个好问题,它取决于调用
ToList
的源序列。如果
temp
是一组正在运行的任务(如您的情况),那么
ToList
只需创建它们引用的副本,这意味着您的新列表将指向同一组任务

但是,如果
temp
构成了一系列尚未实例化的任务(由于延迟执行),那么每次调用
ToList
时都会得到一组新的任务。下面是一个简单的示例(使用
ToArray
,其效果与
ToList
相同):


如果运行上面的代码,最终结果将是
20
,这意味着运行了两批任务(每个
ToArray
调用一批)。但是,如果您取消对启用即时执行的行的注释,最终结果将变为
10
,这表明后续的
ToArray
调用仅复制引用,而不是生成新任务。

MSDN说:“List.ToArray()将ArrayList的元素复制到新数组”(这属于最后一行代码).这意味着它复制了参考资料。在这种情况下,它不会创建新的项目和任务。列表和数组都包含相同的实际任务。我发现了一个非常相关的QA,它很好地解释了这一点:请将您的评论放入您的答案中,因为这是真实的答案。
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();
}
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);