what if I need to execute event handlers in certain order? - c#

I have event, for example like that:
public event EventHandler<NewReadyMessageEventArgs> NewReadyMessage
The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one). I.e. I need certain order of handlers execution.
I understand that in reality handlers will be executed one by one and so I just need to attach them in right order but that would be very error-phrone design.
I want to create separate handler and attach it. In this handler I just want to execute my two handlers in right order. What do you think and what would you suggest?

The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one)
In this case, I would rethink your design. It likely makes more sense for the "first" handler to raise its own event.
The second handler could attach to that event, and have the results of both items.

I would not rely on the internal implementation to ensure that the handlers get called in a specific order.
If the handlers can't know about each other but you need them to run in a certain order I would create a "parent" handler that calls the other two handlers in the correct order.

I would suggest implementing your own add implementation if you don't want the default multicast delegate with the default event add/remove implementation.
For more information see http://msdn.microsoft.com/en-us/library/cc713648.aspx
In case it wasn't obvious, if you don't use the default multicast delegate, invocation of subscribers needs to be implemented manually. The above link details how to write custom add/remove to use a multicast delegate. This answer assumes you don't use a multicast delegate For example, something like:
private List<EventHandler> eventList = new List<EventHandler>();
public event EventHandler Event1
{
add { eventList.Add(value); }
remove { eventList.Remove(value); }
}
private void RaiseEvent1()
{
foreach(var e in eventList)
{
e(this, EventArgs.Empty);
}
}
Use a SortedList if you want a specific order...

It sounds like this might be a place where you just need to have multiple (2) events.
If the order is important have two events, and have one that is simply fired right after the other. You can see this at, for example, the page lifecycle in ASP. There are lots of events, and in some cases they're all fired one after the other with thing really inbetween them other than a guarantee that all handlers of the previous event are run. That sounds just like your case here.

Related

Can I depend on event handlers being invoked in order of registration?

In the current version of the .NET framework, and under normal circumstances (i.e. without intentionally modifying the invocation list), are handlers for an event always invoked in the order in which they are registered? This would be consistent with the documented behavior of multicast delegates, with which events are implemented.
The accepted answer to this question says that invoking handlers in the order of their registration is an implementation detail that may change in some future version of the framework. I believe such a change by Microsoft is unlikely, therefore I am confining my question to the current version of the .NET framework. A comment on that same answer says that it is possible to register handlers such that they are not invoked in their registration order. If this is true then please demonstrate code that results in this out-of-order execution. Please do not include code which intentionally modifies the invocation list. What I am after here is whether or not I can depend on event handler invocation occurring in same order as registration in all current versions of the .NET framework.
You cannot be sure that an event will always be executed in a particular order. The definition of the event can always do whatever it wants, and the implementation of that event is not a part of the public API.
By default, events will use a single multicast delegate as the backing store for an event, but it is straightforward enough to use your own implementation instead. There is no way to tell (beyond looking at the source code) whether or not an event has a custom implementation or not.
One way of implementing an event to not have the described order would be:
public class Foo
{
private Stack<Action> stack = new Stack<Action>();
public event Action MyEvent
{
add
{
stack.Push(value);
}
remove { throw new NotImplementedException(); }
}
internal void OnMyEvent()
{
foreach (var action in stack)
action();
}
}
While most of the events in framework classes won't use a definition like this; most will use a multicast delegate, the only way to know is to look at the source code; you can't tell from, for example, looking at the documentation, whether an event is implemented like this or like:
public class Foo2
{
public event Action MyEvent;
}
That depends on how the event is implemented.
Ordinary (field-like) events store all of their handlers in a single multicast delegate.
Multicast delegates invoke their handlers in insertion order.
Other events are free to store their handlers in some other order. However, most non-standard implementations still use multicast delegates under the covers, stored in various ways (eg, EventHandlerList)

How to find out if an event has fired in another event handler without the use of flags?

I have two events A and B.
I need to check in the event handler of B if the Event A was raised. I know I can do it using a flag but I have used so many flags so far for these kind of situations; and want to use an alternate strategy.
To me this sounds like bad design. If event of A was raised, it should have done something like modifying the state of some object instance. So if event of B is raised, by checking the state changes done by event of A, you should know if it was raised or not. If I am wrong in terms of bad design, then please post more information on your solution.
Example:
void eventOfA(EventArgs args)
{
// modify application or whatever state like
myAppContext.ChangeStatus(2);
// or
myWhateverInstance.DoStuff();
}
void eventOfB(EventArgs args)
{
if(myAppContext.Status == 2)
// eventOfA was raised
else
// eventOfA was not raised
// or
if(myWhateverInstance.DidStuff)
// eventOfA was raised
else
// eventOfA was not raised
}
Maybe you should reconsider the semantic of your events, and create another one.
Say if you have MyApplicationExit and SaveMyData Events, and that you don't need to save everything when application will exit right after, you can indeed check in the SaveMyData Handler wether MyApplicationExit was called before. But a much better choice would be to create another SaveMyDataOnExit event that you send when you are exiting and user want things to be saved. No so much work added since you HAVE to differentiate each case.
All that booleans you need are for Events ? Because if the event handling of .Net doesn't fit you, you might also consider to write your own EventHandler for your custom events, defining the meaning of AddHandler, RemoveHandler and RaiseEvent. So you might create any complex relationship beetwenn events, like raising one event could automatically -or with a condition on the event arg- raise another event, or whatever suits better your needs.

How to manipulate at runtime the invocation list of a Delegate?

I want to know how do I go about removing individual delegates from the invocation list of the parent delegate.
<DelegateName>.RemoveAll();
Now I can just remove all and that will work just to get the idea in motion and see if works which it should but then any delegates removed will need adding again at RunTime!!!
so: ...
foreach(Delegate d in <DelegateName>.getInvocationList)
{ // do something with 'D'?? }
Now that I have access to 'D' I can drop it into a .Remove() but it requies two arguments??? Could I get some help with this please?
Lastly, once the delegate has been removed, what is the best way to re-add it again?
So i'm assuming Reflection might play a part in this but over to you guys.
UPDATE:
Essentially there is a global delegate that has many events living in different winforms classes that are instances of it. All of these events have a handler that handles the event when it is fired. The delegate all the way at the top governs all handlers that match its signature are fired. I want to mess about with this delegate at the top, I want to remove all handlers and then re-add them at run time. So the delegate at the top is a multicast delegate and its invocation list is a list of individual delegates that in turn point to one of the four handlers that I have added. I hope that makes sense, thats a general idea of whats I am doing.
You can't - delegates are immutable. You can create a new delegate which is equivalent to the old one without certain actions, but you can't modify the existing one in-place.
Invocation list is internal piece of delegate, you can't modify it normally. You may be able to do it by very dirty reflection, but i don't think that it is valid idea for production code. But there is another way to solve it validly. You can define event without automatic underlaying delegate and control the invocation list yourself. For that you need to define event with explicit add and remove keywords, see here. You will have to reimplement some stuff for that but it will give you full control.

What use cases exist for non-static private or protected events?

What purpose do protected or private (non-static) events in .NET really serve?
It seems like any private or protected event is more easily handled via a virtual method. I can (somewhat) see the need for this in static events, but not for normal events.
Have you had a use case before that clearly demonstrates a need or advantage for a non-static protected or private event?
Here's a slightly bizarre but real-world scenario I implemented once. You have machine-generated and user-generated halves of a partial class. The machine-generated half contains code which wishes to inform the user-generated half when some event occurs. But the user-generated half might not care to do anything, or it might care to do rather a lot. It seems rude of the machine-generated half to require that the user-generated half implement a particular method in order to handle a message they don't have any interest in listening to.
To solve this problem, the machine-generated half could fire on a private event. If the user-generated half cares, it can subscribe the event. If not, it can ignore it.
This scenario is now addressed more elegantly by partial methods in C# 3, but that was not an option back in the day.
Seems to me that a good example of where a private event is useful is in component/control building, often you may have a component that is a composite of 1 or more other components, private events that contained components can subscribe to is a handy and easy implementation of an observer pattern.
Edit:
Let me give an example...
Say you are writing a Grid type control, and inside of this control you would most likely have a bunch of contained classes that are created dynamically Rows, Cols, headers etc for example, say you want to notify these contained classes that something they care about has happend, say a Skinning change or something like that, something that you don't necesarrily want to expose as an event to the grid users, this is where private events are handy, simply have one or 2 handlers and as you create each instance of your row or col or whatever attach the handler, as otherwise you just have to write your own observer mechanism, not hard, but why when you dont have to and you can just use multicast events.
Nested types have access to the enclosing type's private and protected events. I've used this feature to notify child controls (the nested type) of state changes in the parent control (the enclosing type) in a Silverlight application.
Sorry to drag up an old thread, but I use private events with impunity in one of my projects, and personally, I find it's a good way of solving a design issue:
Here's the abbreviated code:
public class MyClass
{
private event EventHandler _myEvent;
public ExternalObject { get; set; }
public event EventHandler MyEvent
{
add
{
if (_myEvent.GetInvocationList().Length == 0 && value != null)
ExternalObject.ExternalEvent += HandleEvent;
_myEvent+= value;
}
remove
{
_myEvent-= value;
if (_myEvent.GetInvocationList().Length == 0)
ExternalObject.ExternalEvent -= HandleEvent;
}
}
private void HandleEvent(object sender, EventArgs e)
{
_myEvent.Raise(this, EventArgs.Empty); // raises the event.
}
}
Basically, MyEvent is only ever raised in the event handler of ExternalObject.ExternalEvent, so if there's no handlers for MyEvent then I don't need to attach a handler to the external event, speeding up the code slightly by saving a stack frame.
Not only the current instance can access a private member. Other instances of the same type can too! This enables some scenarios where this access control may be useful.
I am thinking of a tree structure where all nodes inherit a certain type and a private/protected event allows to propagate leaf events to their parents. Since they are the same type, the parent can register to the child's private event. Yet any client of the tree structure cannot.
I can definitely see a use case in a directory like storage system where where each directory needs to propagate its last modified date to its parent for example.

Why should derived classes handle an event without attaching a delegate?

Q1:
“The ListControl.OnSelectedIndexChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.”
A) If I understand the above quote, then if we derive a class from ListControl, we should instead of subscribing to SelectedIndexChanged event, treat OnSelectedIndexChanged() method as an event handler and thus put any event processing logic inside it:
protected override void OnSelectedIndexChanged(
EventArgs e
{
//event handling logic
}
Why would that be better than subscribing to an event(inside .aspx) via OnSelectedIndexChanged = ”name_of_event_handler”?
B)
Anyways, in ascx file we use OnSelectedIndexChanged attribute to attach event handler to an event. Name of this attribute is the same as the name of OnSelectedIndexChanged() method. Why is that? Why isn't instead the name of this attribute SelectedIndexChanged:
<asp:ListControl SelectedIndexChanged = ”name_of_event_handler”
Afterall, attribute refers to an event and not to a method ( OnSelectedIndexChanged() ) that calls this event!
thanx
EDIT:
Hello,
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!
Assuming you don’t want anyone else to be able to respond to this event, then would it be perfectly OK not to call base.On[EventName], since I would think not calling it won’t really do any harm besides not firing an event ( and thus event handlers won't be called )?
I realize some events need to be fired in order for Framework to do its job, but what about not calling base.On[SelectedIndexChanged]?
It is "better" in that:
it is cheaper to use virtual (inheritance) where possible - it removes the need for a few extra objects (delegate instances, etc)
it allows the overriding code to know where it comes in the sequence - i.e. if multiple callers are listening, does it fire first? second? in the middle?
The first point is arguably more important for efficiency, especially in things like controls that have sparse event handlers (i.e. things like EventHandlerList instead of a field-like-event).
I don't really understand the second question, but at a guess: convention.
In general, I prefer to override the On[EventName] functions so that I can control if my logic happens before or after the logic in any subscribers.
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!

Categories

Resources