In a previous post, I explained a subtle bug in the way that events are raised in most code. This suble bug might cause a race condition that results in unexpected behavior when the code is executed in multiple threads.
You can read the details here.
From .NET 2 onwards, there is an even simple pattern to solve this problem:
The trick is that the event is initialized to an empty delegate (this was not possible before .NET 2.0). When invoked, this empty delegate does nothing. However it guarantees that the event will never become null, so the race condition cannot occur.
So using this pattern it is always safe to raise the event and it is even not necessary anymore to check if the event is null.