If an event in C# has no delegates registered with it, attempting to raise the event will cause a NullReferenceException. As a result, given an event declared as public event EventHandler MyEvent; you'll often see it raised with code such as: if (MyEvent != null) MyEvent(this, EventArgs.Empty); This works fine in a single-threaded environment, but consider the scenario in which multiple threads are accessing MyEvent simultaneously. In such a case, one thread could check whether MyEvent is null and determine that it isn't. Just after doing so, another thread could remove the last registered delegate from MyEvent. When the first thread attempts to raise MyEvent, an exception will be thrown. A better way to avoid this scenario is shown in the following code snippet: void MyEventInvoke(object sender, EventArgs args) { EventHandler ev = MyEvent; if (ev != null) ev(sender, args); } Whenever a delegate is added to or removed from an event using the default implementations of the add and remove accessors, the Delegate.Combine and Delegate.Remove static methods are used. These methods return a new instance of a delegate, rather than modifying the ones passed to it. In addition, assignments of object references in .NET are thread-safe, and the default implementations of the add and remove event accessors are synchronized. As such, the previous code succeeds by first copying the multicast delegate from the event to a temporary variable. Any changes to MyEvent after this point will not affect the copy you've made and stored. You can now safely test whether any delegates were registered and subsequently invoke them.
Latest Posts
Popular Posts
-
I am *very* keen on automating tests, so I was looking into unit testing a WCF service. If I say "unit test", I mean a fast ,...
-
It's easy I thought, just select the Property of the EntityType and set the Default Value in the Properties window to: DateTime.Now ...
-
*Updated* 26. September 2010: Updated with comments from Adam Cogan *Updated* 27. September 2010: Updated the comparison between anonymo...
No comments:
Post a Comment