C# Events and Thread Safety

The JIT isn’t allowed to perform the optimization you’re talking about in the first part, because of the condition. I know this was raised as a spectre a while ago, but it’s not valid. (I checked it with either Joe Duffy or Vance Morrison a while ago; I can’t remember which.)

Without the volatile modifier it’s possible that the local copy taken will be out of date, but that’s all. It won’t cause a NullReferenceException.

And yes, there’s certainly a race condition – but there always will be. Suppose we just change the code to:

TheEvent(this, EventArgs.Empty);

Now suppose that the invocation list for that delegate has 1000 entries. It’s perfectly possible that the action at the start of the list will have executed before another thread unsubscribes a handler near the end of the list. However, that handler will still be executed because it’ll be a new list. (Delegates are immutable.) As far as I can see this is unavoidable.

Using an empty delegate certainly avoids the nullity check, but doesn’t fix the race condition. It also doesn’t guarantee that you always “see” the latest value of the variable.

Leave a Comment