Chain Event Issue

Note. I edited this question to help other people with the same problem get help here. To see the original question that is best for some answers, check the change history.

In the project, I have an ExecutionManager class that can contain multiple instances of ExecutionSlot. The ExecutionSlot class has several public event fields, such as:

public event EventHandlers.ObjectEventHandler<IPlugin> ExecuteCompleted; 

For each of these events, there is a matching event in the ExecutionManager. The desired behavior is that every time an ExecutionSlot is executed, an event occurs, the corresponding event also occurs in the containing ExecutionManager.

An example solution was that whenever an ExecutionSlot was added to the ExecutionManager, the ExectionManager would add its own events to the ExecutionSlot as follows:

 executionSlot.ExecuteCompleted += ExecuteCompleted; 

There is no need to delete ExecutionSlot, so events are never deleted.

The problem is that the event in the ExecutionManager is not raised. After confirming that the event was viewed using ExecutionSlot, I found that changing the above line to the following was fixed:

 executionSlot.ExecuteCompleted += (sender, eventArgs) => ExecuteCompleted(sender, eventArgs); 

And I could not understand why, so my question was, what is the difference.

The reason for this difference was that the former adds current ExecutionManager event listeners to the ExecutionSlot event. Therefore, any listeners added later will not be called when the event is raised. In contrast, the latter solution uses a lambda to raise an ExecutionManager event, which means listeners will be called during the event.

The main reason for the failure of the first decision is that delegates are immutable. Therefore, when you add a new delegate and event, you actually create a new delegate that contains the existing delegates and the added one. Therefore, any reference to delegates that were made earlier will not contain the newly added delegate.

+6
c # events delegates
source share
4 answers

take a look at fooobar.com/questions/856084 / ...

 b += (s, e) => a(s, e); 

does not match

 b += a; 

It appends the current contents from a to b, so if more handlers enumerate a later, it will not cause them to be called when b starts

+3
source share

One idea ... maybe there is somewhere in your code where you do:

 executionSlot.ExecuteCompleted -= ExecuteCompleted; 

which will unsubscribe from the event if you use the original subscription syntax, but do not delete it after making the changes.

+4
source share

EDIT: This answer suggested that ExecuteCompleted was a method. Because it is actually a field that completely changes things. I will leave this answer here for posterity.

The first version adds an event handler with a delegate created using the auto-generated method, which, in turn, simply calls ExecuteCompleted . This is something like this:

 private void <>AutogeneratedMethodWithUnspeakableName(object sender, EventArgs e) { ExecuteCompleted(e); } ... executionSlot.ExecuteCompleted += <>AutogeneratedMethodWithUnspeakableName; 

The second version adds an event handler with a delegate created directly from the ExecuteCompleted method.

Basically the first form is one additional level of redirection. This usually doesn't make any difference, except for the unsubscribing that JoelFan mentioned. I would suggest that the problem.

A class raising an event may reflect over attached handlers and look at the names of methods, otherwise react in this particular case - but this is very unlikely.

+4
source share

I believe that what happens here is that in the first example, some kind of temporary object is created with an empty event handler, which is called, but does nothing.

The second example, which, as you say, works, is an event handler on your object with real code. Not quite sure what is going on there, but this is my best guess.

Of course, the first example smells bad, because it uses lambda expressions to obfuscate a value without real added value.

0
source share

All Articles