c# - 为什么局部变量在 C# 中不能是 volatile 的?

标签 c# multithreading volatile

public void MyTest()
{
  bool eventFinished = false;

  myEventRaiser.OnEvent += delegate { doStuff(); eventFinished = true; };
  myEventRaiser.RaiseEventInSeperateThread()

  while(!eventFinished) Thread.Sleep(1);

  Assert.That(stuff);
}

为什么 eventFinished 不能是易变的,这有关系吗?

在我看来,在这种情况下,编译器或运行时可能会为了自己的利益而变得聪明,并在 while 循环中“知道”eventFinished 只能为假。尤其是当您考虑将提升变量生成为类成员的方式以及将委托(delegate)生成为同一类的方法时,从而剥夺了对 eventFinished 曾经是局部变量这一事实的优化。

最佳答案

存在一个线程原语,ManualResetEvent准确地完成这项任务 - 你不想使用 bool 标志。

像这样的东西应该可以完成工作:

public void MyTest()
{
    var doneEvent = new ManualResetEvent(false);

    myEventRaiser.OnEvent += delegate { doStuff(); doneEvent.Set(); };
    myEventRaiser.RaiseEventInSeparateThread();
    doneEvent.WaitOne();

    Assert.That(stuff);
}

关于在局部变量上缺少对 volatile 关键字的支持,我认为没有任何理由说明这在理论上 可能 在 C# 中是不可能的。最有可能的是,它不受支持仅仅是因为在 C# 2.0 之前没有使用这样的功能。现在,随着匿名方法和 lambda 函数的存在,这种支持可能会变得有用。如果我在这里遗漏了什么,请有人澄清一下。

关于c# - 为什么局部变量在 C# 中不能是 volatile 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1032154/

相关文章:

c# - 单例仔细检查并发问题

我可以让一个变量暂时不稳定吗?

c# - 在 C# 的构造函数中声明线程

c# - 如何在 for 循环中访问集合 'Length' 属性

c# - 使用 AsParallel 或 Parallel.ForEach 控制线程数

c++ - 成员变量(属性)可以驻留在 C++ 中的寄存器中吗?

c# - 如何使用 Microsoft.SmartDevice.Connectivity 从 WinCe 设备获取目录

c# - ASP.NET MVC UpdateModel 意外失败

java - Spring Boot 中的线程本地行为

java - Java 中的线程状态机