It won't make sure that any changes made by a different thread are used
in the first place though.
Yes you are right, the code only will handle the case if the event is
null or not. It doesn't handle preserving the list itself. If you access
the event directly, there is a chance that in between the check for null,
and the raising of the event, you could get a null reference exception
because another thread has nulled out the list (removed the last event
listener).
I'm sure I've read something about this, but that it turned out not to
be true. I've a sneaking suspicion it was on some blog or other. I
found this:
http://blogs.msdn.com/grantri/archive/2004/09/07/226355.aspx
but I'm not sure it's the same thing.
Yes, this is a similar example. However, you can't place the volatile
keyword on an event, so the solution posted there won't work.
A better solution is to make it thread-safe, IMO.
See
http://www.pobox.com/~skeet/csharp/threads/lockchoice.shtml for my
preferred way of doing things.
I don't think that this is a good way to do this. You have to end up
placing this code at the call site and the declaration of every single event
that you have. This quickly becomes a maintinence issue.
In using a method that will handle the firing of all of your events for
you (or at least the ones that follow the suggested pattern of two
parameters, object o and EventArgs e), and declaring that the method can't
be inlined, you can easily provide nearly the same level of protection
(neither your solution nor mine actually preserves the delegate chain, only
preventing it from being set to null in a multi-threaded environment), and
only have to modify the call site for actually raising the event.
With your way of doing it, though, you gain the advantage of
encapsulating the lock object that is used on the event. In delcaring the
event normally, you end up synchronizing on this, or the Type of the object.
I would say that it is a judgement call whether or not you want to maintain
that much code for that benefit.