C#,MultiThread Lambda 是否使用自由变量有效?
C#, is MultiThread Lambda using free variable Valid?
我想在多线程 Lambda 表达式中使用一些自由变量。
这里是例子,
{
int a = 0;
Thread t = new Thread(() =>
{
SomeBlockingFunc(a);
});
t.Start();
}
无法识别线程何时执行,即使变量作用域已结束。
即使在范围结束后,'int a' 是否有效?
谢谢。
lambda 表达式捕获 a
变量。此代码完全有效。
来自 C# 6 规范草案,section 11.16.6.2:
When an outer variable is referenced by an anonymous function, the outer variable is said to have been captured by the anonymous function. Ordinarily, the lifetime of a local variable is limited to execution of the block or statement with which it is associated (§9.2.8). However, the lifetime of a captured outer variable is extended at least until the delegate or expression tree created from the anonymous function becomes eligible for garbage collection.
区分变量的 scope 和 lifetime 很重要 的变量。
还值得注意的是,它确实仍然是一个变量。多个委托可能会捕获相同的变量。考虑这段代码:
using System;
int value = 0;
Action a = () =>
{
Console.WriteLine($"In first action; value={value}");
value++;
};
Action b = () =>
{
Console.WriteLine($"In second action; value={value}");
value++;
};
a();
a();
b();
a();
这个输出是:
In first action; value=0
In first action; value=1
In second action; value=2
In first action; value=3
如您所见:
- 两个动作捕获了同一个变量
- 两个操作都可以看到每个操作中对变量值所做的更改
我想在多线程 Lambda 表达式中使用一些自由变量。
这里是例子,
{
int a = 0;
Thread t = new Thread(() =>
{
SomeBlockingFunc(a);
});
t.Start();
}
无法识别线程何时执行,即使变量作用域已结束。
即使在范围结束后,'int a' 是否有效?
谢谢。
lambda 表达式捕获 a
变量。此代码完全有效。
来自 C# 6 规范草案,section 11.16.6.2:
When an outer variable is referenced by an anonymous function, the outer variable is said to have been captured by the anonymous function. Ordinarily, the lifetime of a local variable is limited to execution of the block or statement with which it is associated (§9.2.8). However, the lifetime of a captured outer variable is extended at least until the delegate or expression tree created from the anonymous function becomes eligible for garbage collection.
区分变量的 scope 和 lifetime 很重要 的变量。
还值得注意的是,它确实仍然是一个变量。多个委托可能会捕获相同的变量。考虑这段代码:
using System;
int value = 0;
Action a = () =>
{
Console.WriteLine($"In first action; value={value}");
value++;
};
Action b = () =>
{
Console.WriteLine($"In second action; value={value}");
value++;
};
a();
a();
b();
a();
这个输出是:
In first action; value=0
In first action; value=1
In second action; value=2
In first action; value=3
如您所见:
- 两个动作捕获了同一个变量
- 两个操作都可以看到每个操作中对变量值所做的更改