作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用一个管理线程池以运行操作的类。最初它被编码为采取行动(没有参数),我这样调用它:
void LoadTasks()
{
string param;
// some code loops and changes param
{
threadPool.EnqueueTask(() => SomeMethod(param));
}
}
当线程运行时,有些线程运行良好,但有时 param 变量不是我所期望的......它是一个“较新”的值,而不是我打算发送给方法的值。
更改线程池以接受 Action<Object>
并在没有 lambda 的情况下调用——像这样 threadPool.EnqueueTask(SomeMethod, param)
-- 解决了我的问题。
我看到很多关于 C# lambda 的线程安全问题。例如,an accepted answer的 lambdas 线程安全的可能性比您预期的要小得多。我发现有关 lambdas/闭包/作用域的其他问题和答案令人困惑。所以我正在寻找 lambdas 和变量范围的解释,最好与我的示例中的问题相关。
最佳答案
所以问题在于您关闭了您不想关闭的变量。在大多数情况下,最简单的解决方法是创建一个新的局部变量,复制您曾经关闭的变量,然后关闭那个。
所以代替:
for(int i = 0; i < number; i++)
{
threadPool.EnqueueTask(() => SomeMethod(someList[i]));
}
你可以这样做:
for(int i = 0; i < number; i++)
{
int copy = i;
threadPool.EnqueueTask(() => SomeMethod(someList[copy]));
}
现在每个 lambda 都关闭它自己的变量,而不是让所有的 lambda 关闭同一个变量。
关于c# - 多线程和 lambda 变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17574582/
我是一名优秀的程序员,十分优秀!