1

In the method below what is the difference between using

ListThreads.Add(new Task(() => item.Execute()));

and

ListThreads.Add(new Task(item.Execute));

private void Execute()
{
    for (int i = 0; i < ThreadNumber; i++)
    {
        ListObjects.Add(new MyClass(i + 1, ThreadNumber));
    }
    foreach (MyClass item in ListObjects)
    {
        ListThreads.Add(new Task(() => item.Execute()));
        ListThreads[ListThreads.Count - 1].Start();
    }
    Task.WaitAll(ListThreads.ToArray());
}
default
  • 11,485
  • 9
  • 66
  • 102
Willimar
  • 61
  • 9
  • Nothing is different between, (new Task(() => item.Execute()) and new Task(item.Execute). its just the first one is you explicitly writing the call as a Lamda where. – Mike May 14 '14 at 14:02

2 Answers2

2

You ask the difference between

() => item.Execute()

and

item.Execute

The former is a lambda that calls item.Execute. The, item.Execute, is a method group. When they are passed to the constructor of Task they are both converted to a delegate of type Action.

There is quite a difference though. The lambda captures the variable item. And the method group does not. This means that when the lambda is executed, the value of the variable item may be different from its value when you passed the lambda to the constructor of Task.

To make the lambda version equivalent to the method group version you could introduce a local variable:

foreach (MyClass item in ListObjects)
{
    MyClass tmpItem = item;
    ListThreads.Add(new Task(() => tmpItem.Execute()));
    ListThreads[ListThreads.Count - 1].Start();
}

Do note that the language has been modified between C# 4.0 and C# 5.0. In C# 5.0 the code in your question behaves in exactly the same way as does the code above in this answer. For more details see:

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
-2

First of, it's a bad idea to use foreach variable in lambda expression. So, in this particular case the correct way is to write ListThreads.Add(new Task(item.Execute));

Sergey Krusch
  • 1,928
  • 16
  • 17
  • 1
    They do the exact same thing.. and the issue related to using a foreach variable in a lambda expression has been addressed by the C# 5 (?) compiler. – dcastro May 14 '14 at 14:09
  • This is a poor answer due to not actually explaining what's going on. It's also not correct to globally say that lambdas should not be used in `foreach` methods. It's important to realize that lambdas close over *variables* not over *values*, but that doesn't mean you never do it, just that you're careful. You are correct that in C# 4.0 the given code wouldn't reliably function properly, although dcastro is right that in C# 5.0 it would. However in 4.0 a simple local variable copy of the loop variable is a sufficient fix. If you *explained* what's going on, this could be a good answer. – Servy May 14 '14 at 14:14