Fabian
Fabian

Reputation: 55

Task Parallel Library with Action() delegate

Could someone explain me why this code is not working :

...
foreach (VisualChunk chunk in SortedChunks)
{
    System.Action a = () => MyFunction_Threaded(chunk);
    Console.Write("Synchronous : ");
    a.Invoke();
    System.Threading.Tasks.Task.Factory.StartNew(
                                        a,
                                        CancellationToken.None,
                                        TaskCreationOptions.None,
                                        TaskScheduler.Default)
} 
...

private void MyFunction_Threaded(VisualChunk chunk)
{
        Console.WriteLine(chunk.ChunkID);
}

It gives me the following output at console :

Synchronous : 0
Synchronous : 1
Synchronous : 2
Synchronous : 3
Synchronous : 4
Synchronous : 4294967291
Synchronous : 4294967292
Synchronous : 4294967293
Synchronous : 4294967294
Synchronous : 4294967295
Synchronous : 4294967296
Synchronous : 4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
Synchronous : 4294967298
4294967298

In fact this code is working perfectly when .net framework 4.5 is installed (win 8 or VS2012). When only the 4.0 is installed, this problem is raising !

Upvotes: 0

Views: 646

Answers (1)

theMayer
theMayer

Reputation: 16167

Yes, as mentioned in comments above by @usr, the problem in your code is that you have "modified closure," where the compiler is somewhat misinterpreting what you want to do when it builds the assembly language. It is a very poor design choice in the c# language. To get around it, you would need to make a copy of the variable in the loop right away:

foreach (VisualChunk chunk in SortedChunks)
{
  var chunkA = chunk;
  System.Action a = () => MyFunction_Threaded(chunkA);
  ...

However, I would have to ask what the point of this is (i.e. what are you trying to accomplish with this code)?

Upvotes: 1

Related Questions