It is common practice to avoid race conditions (in multi-threaded applications) when triggering events:
EventHandler<EventArgs> temp = SomeEvent; if (temp != null) temp(e); "Remember that delegates are immutable and this is why this technique works in theory. However, what a lot of developers don't realize is that this code could be optimized by the compiler to remove the local temp variable entirely. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible."
The problem (according to the book) is that "this code can be optimized by the compiler to completely remove the local temporary variable. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible"
According to the CLR via C #, here is the best way to get the compiler to copy the event pointer.
virtual void OnNewMail(NewMailEventArgs e) { EventHandler<NewMailEventArgs> temp = Interlocked.CompareExchange(ref NewMail, null, null); if (temp != null) temp(this, e); }
Here CompareExchange changes the NewMail link to null if it is null and does not change NewMail if it is not null. In other words, CompareExchange does not change the value in NewMail at all, but returns the value inside NewMail in atomic thread safe mode. Richter, Jeffrey (2010-02-12). CLR via C # (p. 265). OReilly Media - A. Kindle Edition.
I use the .Net 4.0 framework and I donโt know how this can work because Interlocked.CompareExchange expects a link to a location, not an event link.
Either there is a mistake in the book, or I misinterpreted it. Has anyone implemented this method? Or do you have a better way to prevent race conditions here?
UPDATE
It was my mistake, iterlocked code works. I simply incorrectly defined it, but according to Bradley (below), it is not needed in .net 2.0 and higher on windows.
Sonic soul
source share