多线程和lambda变量范围
本文关键字:范围 变量 lambda 多线程 | 更新日期: 2023-09-27 18:21:55
我正在使用一个管理线程池以运行操作的类。最初,它被编码为采取行动(没有参数),我这样称呼它:
void LoadTasks()
{
string param;
// some code loops and changes param
{
threadPool.EnqueueTask(() => SomeMethod(param));
}
}
随着线程的运行,有些线程很好,但偶尔param变量不是我所期望的。。。这是一个"更新"的值,而不是我想要发送给该方法的值。
将线程池更改为接受Action<Object>
并在没有lambda的情况下调用(如threadPool.EnqueueTask(SomeMethod, param)
)解决了我的问题。
我看到了很多关于C#lambdas的关于线程安全的问题。例如,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都闭合在同一个变量上。