多线程和lambda变量的作用域 [英] multi-threading and lambda variable scope
问题描述
我使用的管理线程来运行操作的池类。它最初被编码为采取行动(不带参数),我在呼唤这样的:
I am using a class that manages a pool of threads to run actions. Originally it was coded to take an Action (with no parameter) and I was calling it like this:
void LoadTasks()
{
string param;
// some code loops and changes param
{
threadPool.EnqueueTask(() => SomeMethod(param));
}
}
由于线程跑一些是不错,但偶尔参数变量是不是我所期待......这是一个新值,而不是我故意要发送到的方法。
As the threads ran some were fine, but occasionally the param variable was not what I expected ... it was a "newer" value and not what I intended to send to the method.
更改线程池来接受动作<对象>
并调用没有一个lambda - 这样 threadPool.EnqueueTask(的someMethod,参数)
- 工作围绕我的问题。
Changing the thread pool to accept Action<Object>
and calling without a lambda -- like this threadPool.EnqueueTask(SomeMethod, param)
-- worked around my problem.
我看到有关线程安全的C#lambda表达式不少问题。例如, lambda表达式的一个公认的答案的就不太可能是线程安全比你期望的那样。的我发现大约lambda表达式/关闭/范围界定等问题和答案是混乱。所以我在寻找lambda表达式和可变范围的解释,最好与在我的例子的问题。
I see quite a few questions about C# lambdas about thread-safety. For example, an accepted answer of lambdas are much less likely to be thread safe than you would expect. I'm finding other questions and answers about lambdas/closures/scoping to be confusing. So I am looking for an explanation of lambdas and variable scope, ideally relating to the problem in my example.
推荐答案
所以,问题是,你在关闭,你不是说要变量。最简单的修补程序是最重要的情况下,是创建一个新的局部变量,复制你曾经关闭过变量,然后关上的是的代替。
So the problem is that you're closing over variables that you don't mean to. The easy fix in most all cases is to create a new local variable, copy the variable you were once closing over, and then close over that instead.
因此,而不是:
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]));
}
现在每个拉姆达被关闭了它自己的变量,而不是所有的人关过的同一个变量。
Now each lambda is closing over it's own variable, rather than having all of them close over the same one variable.
这篇关于多线程和lambda变量的作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!