gpt4 book ai didi

c# - 多线程和 lambda 变量范围

转载 作者:行者123 更新时间:2023-11-30 17:04:20 25 4
gpt4 key购买 nike

我正在使用一个管理线程池以运行操作的类。最初它被编码为采取行动(没有参数),我这样调用它:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com