【发布时间】:2012-02-23 12:29:23
【问题描述】:
闭包捕获的变量如何与不同的线程交互?在下面的示例代码中,我想将 totalEvents 声明为 volatile,但 C# 不允许这样做。
(是的,我知道这是不好的代码,这只是一个示例)
private void WaitFor10Events()
{
volatile int totalEvents = 0; // error CS0106:
_someEventGenerator.SomeEvent += (s, e) => totalEvents++;
while(totalEvents < 10)
Thread.Sleep(100);
}
编辑:人们似乎有点忽略了我的问题。我知道我不能在本地变量上使用volatile。我也知道示例代码代码很糟糕,可以通过其他方式实现,因此我的“错误代码”免责声明。这只是为了说明问题。
无论如何,似乎没有办法将易失语义强制到捕获的局部变量上,所以我将实现一种不同的方式。不过感谢您的回答,无论如何,我学到了一些有用的东西。 :)
【问题讨论】:
-
你希望通过声明变量
volatile获得什么?在大多数情况下,volatile的用户希望它做任何事情,而不是实际做的事情。 -
@Mr.Disappointment - OP 知道这一点 - 这就是为什么他/她说“我想将 totalEvents 声明为 volatile,但 C# 不允许这样做”
-
@Mr.Disappointment - 我相信 OP 确实知道原因 - 这是一个有趣的问题。我认为 OP 试图理解的是:在类级别,由于某些编译器优化,您可以将
volatile应用于一个字段,以确保它可以被多个线程安全地读取和写入(都看到最新值)没有被应用。在上面的示例中,OP 正在使用闭包模拟类似的情况。在该示例中,totalEvents可以被多个线程修改。问题是“你能在这种情况下得到同样的行为吗?如果能,怎么做?” -
@GazTheDestroyer - 我知道你知道 - 我说的是“OP确实理解这一点并且提出了一个好问题”
-
@RobLevine:哎呀,抱歉 Rob,我的用户名弄混了。