使闭包捕获的变量易变
闭包捕获的变量如何与不同的线程交互?在下面的示例代码中,我想将totalEvents声明为volatile,但是C#不允许这样做。
How do variables captured by a closure interact with different threads? In the following example code I would want to declare totalEvents as volatile, but C# does not allow this.
(是的,我知道这是不好的代码,这只是一个示例)
(Yes I know this is bad code, it's just an example)
private void WaitFor10Events()
{
volatile int totalEvents = 0; // error CS0106:
_someEventGenerator.SomeEvent += (s, e) => totalEvents++;
while(totalEvents < 10)
Thread.Sleep(100);
}
编辑:人们似乎没有抓住重点我的问题。我知道我不能在本地变量上使用 volatile
。我也知道示例代码是错误的,可以用其他方式实现,因此我的错误代码免责声明。
EDIT: People seem to be missing the point of my question a bit. I know I can't use volatile
on local vars. I also know that the example code code is bad and could be implemented in other ways, hence my "bad code" disclaimer. It was just to illustrate the problem.
无论如何,似乎没有办法将易失性语义强加到捕获的局部变量上,所以我将采用另一种方式。不过,感谢您的回答,我还是学到了一些有用的东西。 :)
Anyway, it would appear that there is no way to force volatile semantics onto captured local variables, so I will implement a different way. Thanks for the answers though, I have learned a couple of useful things anyway. :)
Volatile。编写救援文件:
Volatile.Write to the rescue:
private void WaitFor10Events()
{
int totalEvents = 0;
_someEventGenerator.SomeEvent += (s, e) => Volatile.Write(ref totalEvents, totalEvents+1);
while(totalEvents < 10)
Thread.Sleep(100);
}
也就是说,我仍然会使用 Interlocked.Increment
针对这种情况。
That said, I would still use Interlocked.Increment
for this particular case..