Search code examples
c#multithreadingvolatile

why can't a local variable be volatile in C#?


public void MyTest()
{
  bool eventFinished = false;

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

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

  Assert.That(stuff);
}

Why can't eventFinished be volatile and does it matter?

It would seem to me that in this case the compiler or runtime could become to smart for its own good and 'know' in the while loop that eventFinished can only be false. Especially when you consider the way a lifted variable gets generated as a member of a class and the delegate as a method of that same class and thereby depriving optimizations of the fact that eventFinished was once a local variable.


Solution

  • There exists a threading primitive, ManualResetEvent to do precisely this task - you don't want to be using a boolean flag.

    Something like this should do the job:

    public void MyTest()
    {
        var doneEvent = new ManualResetEvent(false);
    
        myEventRaiser.OnEvent += delegate { doStuff(); doneEvent.Set(); };
        myEventRaiser.RaiseEventInSeparateThread();
        doneEvent.WaitOne();
    
        Assert.That(stuff);
    }
    

    Regarding the lack of support for the volatile keyword on local variables, I don't believe there is any reason why this might not in theory be possible in C#. Most likely, it is not supported simply because there was no use for such a feature prior to C# 2.0. Now, with the existence of anonymous methods and lambda functions, such support could potentially become useful. Someone please clarify matters if I'm missing something here.