Question

I've read a number of other questions about Access to Modified closure so I understand the basic principle. Still, I couldn't tell - does Parallel.ForEach have the same issues?

Take the following snippet where I recompute the usage stats for users for the last week as an example:

var startTime = DateTime.Now;
var endTime = DateTime.Now.AddHours(6);
for (var i = 0; i < 7; i++)
{
    // this next line gives me "Access To Modified Closure"
    Parallel.ForEach(allUsers, user => UpdateUsageStats(user, startTime, endTime));

    // move back a day and continue the process
    startTime = startTime.AddDays(-1);
    endTime = endTime.AddDays(-1);
}

From what I know of this code the foreach should run my UpdateUsageStats routine right away and start/end time variables won't be updated till the next time around the loop. Is that correct or should I use local variables to make sure there aren't issues?

Était-ce utile?

La solution

You are accessing a modified closure, so it does apply. But, you are not changing its value while you are using it, so assuming you are not changing the values inside UpdateUsageStats you don't have a problem here.

Parallel.Foreach waits for the execution to end, and only then are you changing the values in startTime and endTime.

Autres conseils

"Access to modified closure" only leads to problems if the capture scope leaves the loop in which the capture takes place and is used elsewhere. For example,

var list = new List<Action>();
for (var i = 0; i < 7; i++)
{
  list.Add(() => Console.WriteLine(i));
}
list.ForEach(a => a()); // prints "7" 7 times, because `i` was captured inside the loop

In your case the lamda doing the capture doesn't leave the loop (the Parallel.ForEach call is executed completely within the loop, each time around).

You still get the warning because the compiler doesn't know whether or not Parallel.ForEach is causing the the lambda to be stored for later invocation. Since we know more than the compiler we can safely ignore the warning.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top