multi threading and raising events - c#

I have an application written in c#. I have a class (say called ClassA) that has a simple event (code below). The event is raised to keep the user updated on the progress of the code.
public delegate void MyDelegateProgessUpdate(string value);
public event MyDelegateProgessUpdate ProgressUpdate;
When the application is running a list of ClassA objects are created (up to a maximum of 8). So all 8 objects will be raising an event (in their own class) - this works fine as I have just tested it. However I was wondering if two objects raised an event at the same time if there would be an issue?
Edit
I should have mentioned the following details. The list of ClassA objects will all be running at the same time so it is possible the events could be raised at the same time.
Task[] myTasks = new Task[numThreads];
for (int i = 0; i < myTasks.Length; i++)
myTasks [i] = Task.Factory.StartNew(ClassA[i].DoSomeWork, someData[i]);
This is all being done on a background worker thread. When an event is raised a property on my WPF UI is updated and its OnPropertyChanged event called.

The answer depends solely on the code (your code) that is executed by the events:
IF the code itself is threadsave then no there is no issue. If the code is not 100% threadsave then yes you have a possible problem at your hands (a racing condition to happen).
By itself there is no intricate problem with multiple objects raising the same event. It only depends on the code of the event itself and if the objects have the rights to raise the event.
For example if you are in your own thread and try to raise an event on the GUI which runs in its own thread, then you need to use invoke else you will have a problem
That is if you have code that raises events pretty fast (like multiple handlers set to one event, ....) where your code example doesn't go into details there that show how the events are raised (and how you raise the multiple events)

How will two objects raise events at the same time?
From the code and description you have provided, the is nothing to suggest this is actually multi-threaded code, and your events will be processed in the order that they are raised.
If you do have multiple threads, the important thing to remember is that the event handlers will be run on the thread that raised the event, so be careful if you need to modify any user interface items, and synchronize any access to resources being shared between the threads.
Edit:
I can't really comment with regards to WPF, as my experience is mostly Winforms, however this answer appears to pretty comprehensive with regards to managing cross-thread stuff in WPF.
Other than that I wouldn't expect you to have an issue of the events were raised simultaneously, provided they are not sharing a single set of data between them.

Related

how to obtain Targets of an event

I have an event to fire, named ValueGenerated. The code that generates values and fires ValueGenerated is running in a thread and the method which recieves this event is on a form.control (i.e. a form). As UI thread does not allow another thread to change the UI I wrote the following code on the event generation:
if (ValueGenerated.Target is System.windows.form.control)
{
Control targetForm = ValueGenerated.Target as control;
targetForm.Invoke(ValueChanged,new object[]{this,args});
}
But I think what happens if the event is registered by more than one methode. For example, by two or three destinations. Why on the event and delegate classes we have just the Target property which returns the instance object of the last method added? Do we always need just the last one?
You're doing it wrong.
As noted in the comments, you can get the full list of invocation targets by calling GetInvocationList() on the delegate instance. Then you can invoke each target individually.
But this is not the right way to do it. Your event should treat all handlers the same.
If the event is the kind of event that is always raised in a background thread, and is always handled by a UI object, then it should always use an appropriate mechanism to dispatch to the UI thread. See the BackgroundWorker class for an example of this sort of design, specifically its ProgressChanged and RunWorkerCompleted events.
If either of those conditions are not true, then your event should not attempt to deal with the cross-thread invocation in any way. Subscribers to the event that have thread affinity should be expected to deal with that themselves.
Unfortunately, there's not enough context in your question to provide any more specific advice than that. The only thing that is clear is that you've started down a dead-end road. Turn around, come back, and take the smoother path. :)

What's the benefit of manually adding / removing event handlers, instead of assigning them through the UI?

At work, my old boss would insist we programmatically assign and remove event handlers from our controls in the code behind, rather than simply double clicking a button (for example).
We'd have an AttachEvents() and DetachEvents() method on every single form. I don't remember his explanation as to why this is allegedly better than assigning it from the Design View, and he's since been transferred to a different project. My new manager doesn't know.
I thought he said it had something to do with events not properly being removed from memory, but I really don't know.
So: What is the benefit of doing it this way?
Performance-wise they are the same.
But doing it in the code behind is a much neater way since you control when to AttachEvents() or DetachEvents()
But you have to be careful in terms of avoiding any duplicate event wire ups. These in turn might lead up eating memory, but prominently they would cause performance issues since the event handler would be called as many times as it was wired up.
Some event handlers such as timers need to be removed before leaving a form otherwise they would still fire, for example
timer.Elapsed += ...
and
timer.Elapse -= ...
Probably a good and clear way to remember to do it in this way.
Other than the implications of your own architecture, there's no difference whatsoever.
The designer will place the event subscriptions on the InitializeComponent method and you should not do any changes to that method because the designer might override them or crash if it's something it can't handle.
Usually, the event subscriptions are events the form subscribes from its children. When the from is closed/disposed, all the children are disposed and each child will dispose event subscriptions.
Problems arise when the form subscribes to outside components. Then the form becomes "attached" to those components and, if not unsubscribed, becomes a resource leak.
There's also the possibility of events being fired when the form is not ready to handle them.
I've used a mixed approach where events from child controls were subscribed in the designer (or carefully manually coded in the InitializeComponent method) and used the AttachEvents/DetachEvents approach for components outside the UI (or the scope of the form/control).

Routing an event through multiple classes in C#

A common scenerio we are running into with our current application is where we need to route and event through several classes.
Here is a sample class heirarchy.
ActionManager
MainWindow
PresentationManager
MenuManager
Menu
MenuButton
The Menu subscribes to the click event of a MenuButton. It then creates a CustomAction object and raises an event that is subscribed to MenuManager. In the MenuManager event handler it in turn raises an event that is subscribed to by the PresentationManager, and so on.
Here is a sample of what is implemented for the PresentationManager:
void MenuManager_ActionGenerated(object sender, CustomActionEventArgs e)
{
if (ActionGenerated != null)
ActionGenerated(sender, e);
}
I was hoping that there would be a way that I could raise the event at the Menu level and receive it at the ActionManager level.
Is it bad practise what I am currently doing?
You can also look into Event Aggregator. A good example can be found at codeproject: Event Aggregator with Specialized Listeners
If what you've listed as your class hierarchy is actually your visual tree, it sounds like what you are describing is Routed events.
http://msdn.microsoft.com/en-us/library/ms742806.aspx
Personally, I get scared by having a lot of events. If you are not careful with unsubscription, they can extend the lifetime of your objects. Also, they may cause tight-coupling, reducing testability. In some cases using a Commanding pattern is a better approach.
I would try this CSharpMessenger Extended.
You can write your own SubscriptionManager.
By simplifying can be a Dicationary<string, List<Action<...>>>.
The key is the event-name, value is the List of Actions to run wen that even was raised.
So all yuor components subscribe to some specified event by adding its Action<..> to the list of specified event.
And when the even raised (always via SubscriptionManager) all Action<..>s from the list will be executed.
Just a basic idea. To make this production ready you need to code a bit more.
Good luck.

Why and How to avoid Event Handler memory leaks?

I just came to realize, by reading some questions and answers on StackOverflow, that adding event handlers using += in C# (or i guess, other .net languages) can cause common memory leaks...
I have used event handlers like this in the past many times, and never realized that they can cause, or have caused, memory leaks in my applications.
How does this work (meaning, why does this actually cause a memory leak) ?
How can I fix this problem ? Is using -= to the same event handler enough ?
Are there common design patterns or best practices for handling situations like this ?
Example : How am I supposed to handle an application that has many different threads, using many different event handlers to raise several events on the UI ?
Are there any good and simple ways to monitor this efficiently in an already built big application?
The cause is simple to explain: while an event handler is subscribed, the publisher of the event holds a reference to the subscriber via the event handler delegate (assuming the delegate is an instance method).
If the publisher lives longer than the subscriber, then it will keep the subscriber alive even when there are no other references to the subscriber.
If you unsubscribe from the event with an equal handler, then yes, that will remove the handler and the possible leak. However, in my experience this is rarely actually a problem - because typically I find that the publisher and subscriber have roughly equal lifetimes anyway.
It is a possible cause... but in my experience it's rather over-hyped. Your mileage may vary, of course... you just need to be careful.
I have explained this confusion in a blog at https://www.spicelogic.com/Blog/net-event-handler-memory-leak-16. I will try to summarize it here so that you can have a clear idea.
Reference means, "Need":
First of all, you need to understand that, if object A holds a reference to object B, then, it will mean, object A needs object B to function, right? So, the garbage collector won't collect object B as long as object A is alive in the memory.
+= Means, injecting reference of Right side object to the left object:
The confusion comes from the C# += operator. This operator does not clearly tell the developer that, the right-hand side of this operator is actually injecting a reference to the left-hand side object.
And by doing so, object A thinks, it needs object B, even though, from your perspective, object A should not care if object B lives or not. As object A thinks object B is needed, object A protects object B from the garbage collector as long as object A is alive. But, if you did not want that protection given to the event subscriber object, then, you can say, a memory leak occurred. To emphasize this statement, let me clarify that, in the .NET world, there is no concept of memory leak like a typical C++ unmanaged program. But, as I said, object A protects object B from garbage collection and if that was not your intention, then you can say a memory leak happened because object B was not supposed to be living in the memory.
You can avoid such a leak by detaching the event handler.
How to make a decision?
There are lots of events and event handlers in your whole code-base. Does it mean, you need to keep detaching event handlers everywhere? The answer is No. If you had to do so, your codebase will be really ugly with verbose.
You can rather follow a simple flow chart to determine if a detaching event handler is necessary or not.
Most of the time, you may find the event subscriber object is as important as the event publisher object and both are supposed to be living at the same time.
Example of a scenario where you do not need to worry
For example, a button click event of a window.
Here, the event publisher is the Button, and the event subscriber is the MainWindow. Applying that flow chart, ask a question, does the Main Window (event subscriber) supposed to be dead before the Button (event publisher)? Obviously No. Right? That won't even make sense. Then, why worry about detaching the click event handler?
An example when an event handler detachment is a MUST.
I will provide one example where the subscriber object is supposed to be dead before the publisher object. Say, your MainWindow publishes an event named "SomethingHappened" and you show a child window from the main window by a button click. The child window subscribes to that event of the main window.
And, the child window subscribes to an event of the Main Window.
From this code, we can clearly understand that there is a button in the Main Window. Clicking that button shows a Child Window. The child window listens to an event from the main window. After doing something, the user closes the child window.
Now, according to the flow chart I provided if you ask a question "Does the child window (event subscriber) supposed to be dead before the event publisher (main window)? The answer should be YES. Right? So, detach the event handler. I usually do that from the Unloaded event of the Window.
A rule of thumb: If your view (i.e. WPF, WinForm, UWP, Xamarin Form, etc.) subscribes to an event of a ViewModel, always remember to detach the event handler. Because a ViewModel usually lives longer than a view. So, if the ViewModel is not destroyed, any view that subscribed event of that ViewModel will stay in memory, which is not good.
Proof of the concept using a memory profiler.
It won't be much fun if we cannot validate the concept with a memory profiler. I have used JetBrain dotMemory profiler in this experiment.
First, I have run the MainWindow, which shows up like this:
Then, I took a memory snapshot. Then I clicked the button 3 times. Three child windows showed up. I have closed all of those child windows and clicked the Force GC button in the dotMemory profiler to ensure that the Garbage Collector is called. Then, I took another memory snapshot and compared it. Behold! our fear was true. The Child Window was not collected by the Garbage collector even after they were closed. Not only that but the leaked object count for the ChildWindow object is also shown as "3" (I clicked the button 3 times to show 3 child windows).
Ok, then, I detached the event handler as shown below.
Then, I have performed the same steps and checked the memory profiler. This time, wow! no more memory leak.
Yes, -= is enough, However, it could be quite hard to keep track of every event assigned, ever. (for detail, see Jon's post). Concerning design pattern, have a look at the weak event pattern.
An event is really a linked list of event handlers
When you do += new EventHandler on the event it doesn’t really matter if this particular function has been added as a listener before, it will get added once per +=.
When the event is raised it go through the linked list, item by item and call all the methods (event handlers) added to this list, this is why the event handlers are still called even when the pages are no longer running as long as they are alive (rooted), and they will be alive as long as they are hooked up. So they will get called until the eventhandler is unhooked with a -= new EventHandler.
See Here
and MSDN HERE
I can tell you that this might possibly become an issue in Blazor. You can have a Component subscribing to events using the += syntax and in the long run, this will cause leaks.
The only solution to this (that I'm aware of) is to not use anonymous methods, have the Component inherit from IDisposable and use Dispose() to unsubscribe the event handler.

WPF Firing the RoutedEvents with a Delay

I am gathering all the routed events fired for the MouseRightDownButton and storing them in a Queue. I have the Sender object as well as the RoutedEventArgs.
Now, I need to fire those events one by one and with a little pause. I also want to update the UI as I fire each event.
Do this require the Timer class?
Yes it will require a timer of some sort. I would check out the DispatcherTimer class if you need to update objects on the UI.

Categories