.net-4.0 - 使用并行任务库时“foreach”失败

标签 .net-4.0 parallel-processing task-parallel-library

以下代码创建正确数量的文件,但每个文件都包含第一个列表的内容。谁能发现我做错了什么吗?

private IList<List<string>> GetLists()
{
  // Code omitted for brevity...
}

private void DoSomethingInParallel()
{
  var lists = GetLists();

  var tasks = new List<Task>();

  var factory = new TaskFactory();

  foreach (var list in lists)
  {
    tasks.Add(factory.StartNew(() =>
    {
      WriteListToLogFile(list);
    }));
  }

  Task.WaitAll(tasks.ToArray());
}

最佳答案

原因在于 C# 评估匿名方法的方式,它们不是真正的闭包。这确实与TPL无关。以下代码打印出所有 d。这不是你所期望的

List<Task> tasks = new List<Task>();
List<string> lists = new List<string>();
lists.AddRange(new string[] { "a", "b", "c", "d" });

foreach (var list in lists)
{
    tasks.Add(Task.Factory.StartNew(() =>
    {
        Console.WriteLine(list);
    }));
} 

原因是因为创建匿名方法list的值不是在方法主体中计算的值。使用方法执行list的值。您可以通过执行以下操作强制修复此问题:

List<Task> tasks = new List<Task>();
List<string> lists = new List<string>();
lists.AddRange(new string[] { "a", "b", "c", "d" });

foreach (var list in lists)
{
    var localList = list;  
    tasks.Add(Task.Factory.StartNew(() =>
    {
        Console.WriteLine(localList);
    }));
} 

您不必显式地将列表值传递给匿名方法。

这篇博文对此进行了更详细的介绍:

Link

关于.net-4.0 - 使用并行任务库时“foreach”失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2956328/

相关文章:

c# - 将线程添加到集合时处理 TPL 中的错误

c# - 对如何构造调用 SmtpClient.SendMailAsync() 的异步/等待代码感到困惑

c# - 控件不在焦点时下拉列表更改所选值

.net - 使用Assembly.LoadFrom的loadFromRemoteSources错误

c# - 任务不能并行运行

parallel-processing - MPI Fortran WTIME 运行不正常

sharepoint - 我可以在 SharePoint 2007 中使用 .NET 4 吗?

ASP.NET MembershipProvider 加密/解密

python - 大文本文件的并行计算

c# - 等待具有不同结果的多个任务