This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a downside to adding an anonymous empty delegate on event declaration?
The following pattern is quite common when using event handlers (in C#):
public event Action handler;
…
// some method:
if(handler != null) handler();
Are there any downsides of assigning an empty delegate to this event? This would save the if !=null condition everywhere, where the event is fired. Of course, this only applies, when the we cannot guarantee that the event is always assigned a proper delegate.
public event Action handler;
…
// in constructor:
handler += ()=>{};
…
// some method:
handler();
Sure, there's a slight performance hit, but it makes the code much cleaner. What's the best practice in such a case? Any technical disadvantages?
Interesting idea, I've never thought of doing that. The way i do my custom events is i make a OnCustomEventName taking parameters for the event and just do the check in there for null. and call OnCustomEventName from the code wherever i want the event triggered from.
Avoids any performance hits and keeps the operational code cleaner than a 2-line if check every time you want the event fired.
That being said this isn't answering the question about technical disadvantages but more of a best practice when firing events.
example code for threadsafe "On" function.
private void OnCustomEventName()
{
DelegateName localhandler = CustomEventName;
if (localhandler != null)
localhandler();
}
Instead of adding an empty delegate in the constructor, you can wrap the handler in a function which first checks if the handler is null then calls it. The downside of this is if you have a lot of events, you will have a lot of functions that wrap each event.
private void HandlerWrapper()
{
Action localHandler = handler;
if (localHandler != null) handler();
}
I haven't really found any big downsides to do this and generally I prefer it over checking for null. The only issue I cant think of is that it might lead to annoying steps in the code when debugging (i.e.
having to step over the empty delegate whenever stepping into an event).
I think that performance isn't an issue - if application performance degenerates significantly by invoking events, the event should probably not have been there in the first place.
Related
One thing that I find slightly annoying is having to null-check events. An event that has no subscribers is going to be null, so often times code like this has to be written:
MyEvent?.Invoke()
One solution for this problem I've found was this initialization pattern, where we initialize event with a no-op delegate:
public event Action MyEvent = delegate { };
Now, since this event is always going to have at least one dummy subscriber, we no longer have to check for null:
MyEvent.Invoke()
While this is pretty convenient, I was wondering whether this pattern a good practice, or is there some reason that I don't see that would make this a bad decision (aside from having to call an extra dummy subscriber, but I am fine with that)? Thanks.
Lets say that I have this (incomplete) class, in which I raise an event without first assigning it to a variable to make it thread-safe:
public class Test
{
public event EventHandler SomeEvent;
void OnSomeEvent(EventArgs e)
{
if (SomeEvent != null)
SomeEvent(this, e);
}
}
Would it be safe to unsubscribe an event handler from itself, or could there be any problem similar to what would happen when removing items from a collection while enumerating it?
void SomeEventHandler(object sender, EventArgs e)
{
testInstance.SomeEvent -= SomeEventHandler;
}
To clarify the other answer a bit:
Events are based on delegates (in almost all cases). Delegates are immutable. This applies to multicast delegates, too.
When invoking an event the delegate is loaded and then invoked. If the field that the delegate is stored in is modified then this does not affect the already loaded delegate.
It's therefore safe to modify the event from the handler. Those changes will not affect the currently running invocation. This is guaranteed.
All of this only applies to events backed by a delegate. C# and the CLR support custom events that could do anything at all.
It would be safe, however, just know it is not a guarantee that the code in SomeEventHandler will be executed only once. A race condition might occur if you have multithreaded code.
Edit:
Unsubscribing from an event will, behind the scenes, combine delegates to produce a list of delegates. (Lots of details can be found on that article by Jon Skeet the man himself)
Note that the event uses locks to guarantee thread safety on the Delegate combination. Once you have combined a delegate to your event, you will have a resulting list of delegates. When raising an event, however, what is not guaranteed is that the latest version of the combined delegates will be used. (see Thread-safe events) but this is unrelated to the fact the event was un-hooked from the inside of the event.
I hope my edit provides enough clarification :)
I've just encountered a bug in the program I'm writing where an exception was thrown stating an "object reference must be set to an instance of an object". Upon investigation, I found that this exception was thrown when trying to fire an event BUT the event didn't have any delegate methods added to it.
I wanted to check that my understanding was correct that as a developer you shouldn't fire events without first checking that the event doesn't equal null? For example:
if (this.MyEventThatIWantToFire != null)
{
this.MyEventThatIWantToFire();
}
Thanks in advance for the advice/thoughts.
The pattern you've shown is broken in a multi-threaded environment. MyEventThatIWantToFire could become null after the test but before the invocation. Here's a safer approach:
EventHandler handler = MyEventThatIWantToFire;
if (handler != null)
{
handler(...);
}
Note that unless you use some sort of memory barrier, there's no guarantee you'll see the latest set of subscribers, even ignoring the obvious race condition.
But yes, unless you know that it will be non-null, you need to perform a check or use a helper method to do the check for you.
One way of making sure there's always a subscriber is to add a no-op subscriber yourself, e.g.
public event EventHandler MyEventThatIWantToFire = delegate {};
Of course, events don't have to be implemented with simple delegate fields. For example, you could have an event backed by a List<EventHandler> instead, using an empty list to start with. That would be quite unusual though.
An event itself is never null, because the event itself is just a pair of methods (add/remove). See my article about events and delegates for more details.
You shouldn't do it that way - if someone where to remove a listener between the if and the call to the event, you'd get an exception. It is good practise to use it with a local variable:
protected void RaiseEvent()
{
var handler = Event;
if(handler != null)
handler(this, EventArgs.Empty);
}
Of course, this has the disadvantage of maybe calling a listener that already was removed between the creation of the local variable and the call to the handler.
Yes, you should check it for null but the way you're doing it leads to a race condition. It's possible the event may end up being null anyway if someone unsubscribes the last delegate in between your "if" and your event raise. The accepted way to do this is like:
var temp = this.MyEventThatIWantToFire;
if (temp != null) {
this.temp(this, EventArgs.Empty);
}
or alternatively, ensure there's always at least one delegate in the invocation list by declaring your event like this:
public event EventHandler MyEventThatIWantToFire = delegate {};
Make sense?
Yes, your understanding is correct. It's up to you to check the delegate's value before calling it.
Most delegates - which events are - are "multi-cast" delegates. This means that a delegate can manage a list of one or more methods that it will call when activated.
When the delegate evaluates to a null value, there are no registered methods; therefore, there is nothing to call. If it evaluates to something other than a null value, there is at least one method registered. Calling the delegate is an instruction to call all methods it has registered. The methods are called in no guaranteed order.
Using the addition-assignment operator (+=) or addition operator (+) adds a method to the delegate's list of methods. Using the subtraction-assignment operator (-=) or subtraction operator (-) removes a method from the delegate's list of methods.
Also note that the called methods are executed from the caller's thread. This is important if you are using events to update your user interface controls. In this situation, use of your control's InvokeRequired property lets you handle cross-threading calls (using Invoke() or BeginInvoke()) gracefully.
Yes in C# if an event has no delegates, it will be null, so you must check
Yes, you must check whether event is not null. Mostly you encounter protected method that does the check and invokes event, or even constructs event args. Something like this:
public event EventHandler Foo;
protected void OnFoo() {
if (Foo == null)
return;
Foo(this, new EventArgs());
}
This approach also alows your derived classes to invoke (or prevent invoking) the event.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is there a downside to adding an anonymous empty delegate on event declaration?
Is it a good practice to define an empty delegate body for a event so that you do not need to worry raise a event which have no event handler? ( no need to check whether event is null).
Like code below:
public event EventHandler<LoadEventArgs> LoadedData = delegate { };
I've certainly found it useful, yes. There will be a tiny, tiny performance cost - but the benefit in readability for not having to perform the nullity test makes it worth it IMO.
It's worth pointing out that this is one of the few times when it's good to use an anonymous method rather than a lambda expression - otherwise you have to name the parameters that you're going to ignore, like this:
public event EventHandler<LoadEventArgs> LoadedData = (sender, args) => {};
I don't like having to name things I'm not intending to use :)
I would not do this.
There are two reasons for this. Firstly, it's standard to simply check the handler for null before calling this. You see this all over the place, in examples, in the Microsoft reference source and in the manuals.
Second, initializing your events this way allocates unnecessary objects when creating your class. This will put extra memory pressure on your application without a real need. This is because:
public event EventHandler<LoadEventArgs> LoadedData = delegate { };
translates to:
public event EventHandler<LoadEventArgs> LoadedData = new EventHandler<LoadEventArgs>delegate { });
If you don't do this already, wrapping your events in specific methods helps a lot:
public event EventHandler MyEvent;
protected virtual void OnMyEvent(EventArgs e)
{
if (MyEvent != null)
MyEvent(this, e);
}
You can make this thread safe(r) using the following:
public event EventHandler MyEvent;
protected virtual void OnMyEvent(EventArgs e)
{
var handler = MyEvent;
if (handler != null)
handler(this, e);
}
I don't normally use C# but it seems like good practice to me. This is a textbook application of the 'Null Object' pattern. As noted, this will cost in terms of performance when the empty delegate actually runs, but gains in terms of performance every other time, when you don't have to check for an explicit null - so it should also be a net win performance-wise whenever the frequency of empty delegates is low.
This question already has answers here:
C# Events and Thread Safety
(15 answers)
Closed 10 years ago.
So i've read around that instead of calling a event directly with
if (SomeEvent != null)
SomeEvent(this, null);
i should be doing
SomeEventHandler temp = SomeEvent;
if (temp != null)
temp(this, null);
Why is this so? How does the second version become thread safe? What is the best practice?
IMO, the other answers miss one key detail - that delegates (and therefore events) are immutable. The significance of this is that subscribing or unsubscribing an event handler doesn't simply append/remove to a list - rather, it replaces the list with a new one with an extra (or one less) item on it.
Since references are atomic, this means that at the point you do:
var handler = SomeEvent;
you now have a rigid instance that cannot change, even if in the next picosecond another thread unsubscribes (causing the actual event field to become null).
So you test for null and invoke it, and all is well. Note of course that there is still the confusing scenario of the event being raised on an object that thinks it unsubscribed a picosecond ago!
Events are really syntactic sugar over a list of delegates. When you invoke the event, this is really iterating over that list and invoking each delegate with the parameters you have passed.
The problem with threads is that they could be adding or removing items from this collection by subscribing/unsubscribing. If they do this while you are iterating the collection this will cause problems (I think an exception is thrown)
The intent is to copy the list before iterating it, so you are protected against changes to the list.
Note: It is however now possible for your listener to be invoked even after you unsubscribed, so you should make sure you handle this in your listener code.
Best practice is the second form. The reason is that another thread might null or alter SomeEvent between the 'if' test and the invocation.
Here is a good write up about .NET events and race conditions with threads. It covers some common scenarios and has some good references in it.
Hope this helps.