C#,使用自由变量的 MultiThread Lambda 是否有效?

C#, is MultiThread Lambda using free variable Valid?

提问人:Retalia K 提问时间:2/16/2022 更新时间:2/16/2022 访问量:109

问:

我想在 MultiThread Lambda 表达式中使用一些自由变量。

举个例子,

{
   int a = 0;
   Thread t = new Thread(() => 
   {
        SomeBlockingFunc(a);
   });
   t.Start();
}

我无法识别 Thread t Execute 何时结束,甚至变量范围也结束了。

即使在范围结束后,“int a”是否有效?

谢谢。

C# 多线程 Lambda 作用域 自由变量

评论


答:

4赞 Jon Skeet 2/16/2022 #1

lambda 表达式捕获变量。此代码是完全有效的。a

摘自 C# 6 规范草案第 11.16.6.2 节

当外部变量被匿名函数引用时,外部变量被称为已被匿名函数捕获。通常,局部变量的生存期仅限于执行与其关联的块或语句 (§9.2.8)。但是,捕获的外部变量的生存期至少会延长,直到从匿名函数创建的委托树或表达式树符合垃圾回收条件。

区分变量的作用域(只是标识符引用该变量的代码部分)和变量的生存期非常重要。

还值得注意的是,它确实仍然是一个变量。多个委托可能会捕获相同的变量。请考虑以下代码:

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

正如你所看到的:

  • 这两个操作捕获了相同的变量
  • 两个操作都可以看到在每个操作中对变量值所做的更改

评论

0赞 Retalia K 2/16/2022
这个答案对我有用。我做了一些测试,我获得了信心。谢谢:)