"foreach" does not work when using Parallel Task Library

The following code creates the correct number of files, but each file contains the contents of the first list. Can anyone notice what I did wrong?

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());
}
+2
source share
4 answers

Sorry for not responding to this before. I found a solution - although I do not understand why it works ...

Initially, I had this ...

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

Changing the serial foreach to parallel foreach fixes the problem ...

Parallel.ForEach<string>(lists, list =>
    tasks.Add(factory.StartNew(() =>
    {
      WriteListToLogFile(list);
    }));
  );
+1
source

The reason why C # evaluates anonymous methods is that they are not true closures. This has nothing to do with TPL. The following code prints all d's. This is not what would be expected during the year.

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);
    }));
} 

.

:

http://blogs.msdn.com/b/abhinaba/archive/2005/10/18/482180.aspx

+4

, "", .

: factory.StartNew System.Threading.Tasks.Task!!

Thinking out loud: why List<String>is there a separate task for each one in its list that calls WriteListToLogFile?

I think you will need to use

ThreadPool.QueueUserWorkItem 

in your code after task.Add

look at this example (see accepted answer) link

0
source

Go to the same problem yourself. I'm still not sure why this is happening, but I was able to get it to work correctly by passing a state object

 foreach (var list in lists) 
  { 
    tasks.Add(factory.StartNew((o) => 
    { 
      var l = o as List<string>;
      WriteListToLogFile(l); 
    }, list)); 
  } 
0
source

Source: https://habr.com/ru/post/1790580/


All Articles