繁体   English   中英

Parallel.ForEach - 访问修改后的闭包适用?

[英]Parallel.ForEach - Access To Modified Closure Applies?

我已经阅读了一些关于访问修改闭包的其他问题,所以我理解了基本原理。 不过,我无法分辨 - Parallel.ForEach是否有同样的问题?

以下面的代码片段为例,重新计算上周用户的使用情况统计数据:

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

根据我对此代码的了解, foreach应该立即运行我的UpdateUsageStats例程,并且开始/结束时间变量将不会更新,直到下一次循环。 这是正确的还是我应该使用局部变量来确保没有问题?

正在访问修改后的闭包,因此它确实适用。 但是 ,您在使用它时不会更改其值,因此假设您没有更改UpdateUsageStats的值,则此处没有问题。

Parallel.Foreach等待执行结束,然后才改变startTimeendTime的值。

“访问修改后的闭包”只会在捕获范围离开捕获发生的循环并在其他地方使用时导致问题。 例如,

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

在你的情况下,执行捕获的lamda不会离开循环( Parallel.ForEach调用在循环内完全执行,每次都是)。

您仍然会收到警告,因为编译器不知道Parallel.ForEach是否导致存储lambda以供以后调用。 由于我们知道的不仅仅是编译器,我们可以安全地忽略警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM