C# UI events unsubscription - necessary? - c#

I know unsubscription from event IS necessary.
My questions comes from the generated code:
When you modify an ui from the VS editor, and add an event handler to a UI element (ex:
private void BtnSampleClick(object sender, EventArgs e))
When creating this event handling, VS adds this code in the private void InitializeComponent() autogenerated code
this.btnSample.Click += new System.EventHandler(this.BtnSampleClick);
Problem is that VS doesn't add the unsubscription (this.btnSample.Click -= new System.EventHandler(this.BtnSampleClick); ) automatically in the Dispose method of the form.
Normally we should add them there right? If not this will leak to memory leaks?
Wanted to check if there was a reason why VS doesn't perform the unsubscription automatically. Maybe the form is correctly disposed even if we don't do it?
Thanks for helping me shred some light in this matter!

This isn't done, mainly because it's really not necessary in this case. The reason is that your Form is subscribing to events of objects which have a lifetime managed by the form. When the object (ie: the button) is unrooted from a GC perspective, the form will also be unrooted (and closed), so there is no chance of a memory leak. The GC in .NET is smart - circular references like this are not an issue.
Unsubscribing to events is still a good general practice, however. It becomes important if you subscribe to an event on an object which has a lifetime independent of the object which is making the subscription. This is especially true if the object with the event is much longer lived than the subscriber. This case is where event-caused memory leaks tend to occur. For example, if your Form subscribes to an event on a static instance, and forgets to unsubscribe, the form will never get garbage collected, since the delegate reference will keep it "rooted" via the event subscription.

Yes, it is a good practice to unsubscribe explicitly. Although they can cause memory leaks, as long as they are not holding any reference to unmanaged objects, GC can still correctly determine and cleanup in the managed world.

You need not to care about that. Dot.NET framework has a Garbage Collector (GC) that automatically dispose using its own principle (may be when there is no reference to the object left).
That does not mean you will never need to call Dispose function, in some case you intentionally call Dispose() method so that the memory does not run out, or when we work with native dll / Marshal class

Related

do i have to unsubscribe from events when closing a window in wpf?

the tiltle says it all, in my window (not the main window) constructor i have
EventAggregator.OnUserLoggedIn += OnUserLoggedIn;
EventAggregator.OnUserLoggedOff += OnUserLoggedOff;
is there a difference between
this.Close()
and
EventAggregator.OnUserLoggedIn -= OnUserLoggedIn;
EventAggregator.OnUserLoggedOff -= OnUserLoggedOff;
this.Close()
i've read that closing the window disposes all unmanged resources, are those events considered maneged or unmanaged?
Those events are managed resources if anything (I'm not sure if you can call events resources though).
Yes, you should unhook event handlers from child windows (not main window as it doesn't matter) otherwise you may experience memory leaks as garbage collector won't be able to pick up those objects as still having references.
Check this blog for more info on memory leaks and event handlers:
A classic leak common to all .NET applications, and a common oversight by developers. If you create an event handler to handle events occurring in some other object then, if you don't clear the link when you've finished, an unwanted strong reference will be left behind.
If you are closing the main window and your application will terminate after that you don't have to worry about unhooking the handler. All memory associated with your process is available for reclaim once process terminates.
But in case you are talking about secondary window here and your process will continue to run , you should consider unhooking the events since window will always be in memory as long as EventAggregator stays in memory and resulting in memory leak in your window class.
Publisher (EventAggregator) will hold on to the subscriber object (window) as long as it stays in memory. So, window object will persist with the lifetime of EventAggregator object.

Can I add an on close event to current thread

Is there any way to add an event to the current thread that is executed when the thread ends.
I have a solution where we create resources that we want to re-use but still need to have disposed when the thread ends to prevent leaks and I cannot trust every one to be diligent in adding manual dispose calls to their code.
I could do this with a wrapper around the thread but that will not be a reliable solution as I will not be able to make 100 % sure every one would use the wrapper and sometimes this might need to be added into an existing thread.
So I would need my resource to be able to add a dispose event to be called when the tread finishes.
Is this possible in C#
are we all talking about the same .net here? just impliment Finalize
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
this is the way to tell the 'GC' to do some additional actions when clearing a resource.
If you expect developers may forget to call Dispose() on object, there is another pattern which can be used to force them to call such methods. This is inspired from how database transactions work.
The idea is you use the object which exposes two methods. Complete() and RollBack(). At the end of object lifespan, developer needs to call Complete() for things to work. If he fails to comply, object's destructor (or Dispose()) will call RollBack(). In .NET TransactionScope class is a good example.
In your case you need to encapsulate your thread object inside this class. The caller doesn't directly deal with thread object, but it deals with this class object.
Is there any way to add an event to the current thread that is executed when the thread ends?
No, there's no event in the framework that you can subscribe to.
As you say, one solution would be to wrap the thread main method with a try / finally block.
Another solution would be to rely on the GC. If someone forgets to call Dispose, the destructor will still be called some time after the object goes out of scope - it will be called on the finalizer thread, though.

Should I implement a Dispose for a User Control that has event handlers?

I have a Custom control CustomContainer, that contains another series of custom controls (CustomButtons).
So control CustomContainer has 5 CustomButtons's.
Each CustomButtons has and Click eventhandler that is wired up in the constructor of CustomContainer.
Do I need to write an override Dispose for Control CustomContainer (As it inherits from UserControl there is a Dispose) to un-wire these CustomButtons event handlers? Is the standard Disposing sufficient or will I have a memory leak here?
Thanks,
A.
In most cases involving control events, one can abandon events without disposing them and not run into trouble, because the event publisher and subscriber will generally go out of scope at about the same time. In some ways, this is unfortunate, since if event cleanup were considered necessary for correctness, there would probably be language support for it, and any decently-written code would clean up events as a matter of course.
The problem is that anything keeps an abandoned event publisher from being garbage-collected will also prevent any of its subscribers from being garbage-collected; if those subscribers publish any events of their own, all of their subscribers will likewise be needlessly sheltered from garbage-collection, etc. Suppose, for example, that one has a program that's working beautifully, but one adds an event to let a form know when another form is opened or closed, so that each form can have a "Windows" menu listing other open forms. Nice feature. If, however, a form is disposed without unsubscribing from the event providing such notifications, such failure may prevent the form, or any of its controls, nor any other objects to which those things hold references, from ever being collected. A significant memory leak, though one which will likely only cause problems if multiple documents are opened and closed during the lifetime of the program, and which may thus not be discovered except by the end user.
My recommendation would be to use the form's Disposed event to handle event cleanup. One could change the Dispose code generated by the designer, and the designer would probably leave those changes alone, but given that the Disposed event exists, I would think it cleaner to avoid any tinkering with the designer-generated files.
No, you do not need to implement IDisposable and implement Dispose() only for un-subscription from event handlers you have. The presence of that event handlers you have (button clicks, according to post) will not cause a memory leaks.
IDisposable is used to clean up unmanaged resources. All the managed resource are cleaned up by the garbage collector. When there are no more references to the object , the next time the GC run it will free up everything not accessible from the application.

IDisposable implementation - What should go in 'if (disposing)'

I have been fixing some memory leak issues in a winforms application and noticed some disposable objects that are not Disposed explicitly (developer hasn't called Dispose method). Implementation of Finalize method also doesn't help because it doesn't go in if (disposing) clause. All the static event unregistering and collection clearing have been put in if (disposing) clause. The best practice is calling the Dispose if the object is disposable, but unfortunately this happens sometimes
If there are unmanaged objects, static event handlers and some managed collections that needs to clear when disposing. What's the way to decide what should go in and what should go out of if (disposing) clause.
Dispose method.
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
disposed = true;
}
}
It says managed objects should in if (disposing) which executes normally only when explicitly call Dispose method by the developer. If the Finalize method has been implemented and developer forgets to call the Dispose method the execution that comes here through the Finalizer does not go in if (disposing) section.
Below are my questions.
If I have static event handlers that causes memory leaks where should I un-register them? In or out of if (disposing) clause?
If I have some collections that causes memory leaks where should I clear them? In or out of if (disposing) clause?
If I am using third party disposable objects (eg: devExpress winform controls) that I am not sure whether they are managed or unmanaged objects. Let's say I want to dispose them when disposing a form. How can I know what are managed and what are non-managed objects? Being disposable doesn't say that? In such cases how to decide what should go in and what should go out of if (disposing) clause?
If I am not sure something managed or unmanaged what can be the bad consequences of disposing/clearing/unregistering-events out of the if (disposing) clause? Let's say it checks for null before disposing?
Edit
What I mean as event un-registering is something like below. Publisher is a long lived instance and below line is in the subscriber's constructor. In this case subscriber need to unregister the event and dispose before the publisher.
publisher.DoSomeEvent += subscriber.DoSomething;
Broadly, managed resources are disposed inside if (disposing) and unmanaged resources outside of it. The dispose pattern works as such:
if (disposed) {
If this object is already disposed, don't dispose of it a second time.
if (disposing) {
If disposal was requested programatically (true), dispose of managed resources (IDisposable objects) owned by this object.
If disposal was caused by the garbage collector (false), do not dispose of managed resources because the garbage collector may have already disposed of the owned managed resources, and will definitelty dispose of them before the application terminates.
}
Dispose of unmanaged resources and release all references to them. Step 1 ensures this only happens once.
disposed = true
Flag this object as disposed to prevent repeated disposal. Repeated disposal may cause a NullReferenceException at step 2 or 3.
Question 1
Don't dispose of them in the Dispose method at all. What would happen if you disposed of multiple instances of the class? You'd dispose the static members each time, despite them already being disposed. The solution I found was to handle the AppDomain.DomainUnloaded event and perform static disposal there.
Question 2
It all depends if the items of the collection are managed or unmanaged. It's probably worth creating managed wrappers that implement IDisposable for any unmanaged classes you are using, ensuring all objects are managed.
Question 3
IDisposable is a managed interface. If a class implements IDisposable, it's a managed class. Dispose of managed objects inside if (disposing). If it doesn't implement IDisposable, it is either managed and does not require disposing, or is unmanaged and should be disposed outside of if (disposing).
Question 4
If the application terminates unexpectedly, or doesn't use manual disposal, the garbage collector disposes of all objects in random order. The child object may be disposed before it's parent is disposed, causing the child to be disposed a second time by the parent. Most managed objects can safely be disposed multiple times, but only if they've been built correctly. You risk (though, unlikely) causing the gargabe collection to fail if an object is disposed multiple times.
The key to remember here is the purpose of IDisposable. It's job is to help you deterministically release resources that your code is holding, before the object is garbage collected. This is actually why the C# language team chose the keyword using, as the brackets determine the scope that the object and it's resources are required for by the application.
For instance, if you open a connection to a database, you want to release that connection and close it ASAP after you have finished with it, rather than waiting for the next garbage collection. This is where and why you implement a Disposer.
The second scenario is to assist with unmanaged code. Effectively this is anything to do with C++/C API calls to the operating system, in which case you are responsible for ensuring that the code isn't leaked. As much of .Net is written to simply P/Invoke down to the existing Win32 API this scenario is quite common. Any object which encapsulates a resource from the operating system (e.g. a Mutex) will implement a Disposer to allow you to safely and deterministically release it's resources.
However these APIs will also implement a destructor, to guarantee that if you don't use the resource correctly that it will not be leaked by the operating system. When your finalizer is called, you do not know whether or not other objects you were referencing have already been garbage collected, which is why it is not safe to make function calls upon them (as they could throw NullReferenceException), only the unmanaged references (which by definition cannot be garbage collected) will be available to the finalizer.
Hope that helps a bit.
If I have static event handlers that causes memory leaks where should I un-register them? In or out of if (disposing) clause?
Dispose method is called on instances where as static event handler are used at class level. So you should not un-register them at all in dispose. Usually static event handler should be un-register when class is unloading or at some point during the execution of application you derive that this event handler is no more required.
For all manages and un-managed resources better implement IDisposable pattern.
See here
http://msdn.microsoft.com/en-us/library/fs2xkftw%28VS.80%29.aspx
and
Finalize/Dispose pattern in C#
It sounds like you mainly have managed objects, i.e. objects that implement IDisposable. Unmanaged code would be things like IntPtr's or handles, which would normally mean calling unmanaged code or P/Invoke to get to them.
As Maheep pointed out, Dispose is not meant for this. When an object is done receiving events it should unregister itself. If that's not possible, consider using WeakReferences instead.
This probably shouldn't go in dispose unless these collections contain objects that need to be disposed. If they are disposable objects then it should go in the "if disposing" block and you should call dispose on each item in the collection.
If it implements IDisposable it's managed
You shouldn't access other managed code objects when called by the finalizer which is what being outside the "if (disposing)" block means.
Unless the sole purpose of a class is to encapsulate some resource(*) which needs to be cleaned up if abandoned, it shouldn't have a finalizer, and Dispose(bool) should never be called with a value of False, but calling Dispose(False) should have no effect. If an inherited class would need to hold a resource requiring cleanup if abandoned, it should encapsulate that resource into an object devoted solely to that purpose. That way, if the main object gets abandoned and nobody else holds any reference to the object encapsulating the resource, that object can perform its cleanup without having to keep the main object alive for an extra GC cycle.
Incidentally, I dislike Microsoft's handling of the Disposed flag. I would suggest that the non-virtual Dispose method should use an integer flag with Interlocked.Exchange, to ensure that calling Dispose from multiple threads will only result in the dispose logic being performed once. The flag itself may be private, but there should be a protected and/or public Disposed property to avoid requiring every derived class to implement its own disposal flag.
(*) A resource isn't some particular type of entity, but rather a loose term that encompasses anything a class may have asked some outside entity to do on its behalf, which that outside entity needs to be told to stop doing. Most typically, the outside entity will have granted the class exclusive use of something (be it an area of memory, a lock, a GDI handle, a file, a socket, a USB device, or whatever), but in some cases the outside entity may have been asked to affirmatively do something (e.g. run an event handler every time something happens) or hold something (e.g. a thread-static object reference). An "unmanaged" resource is one which will not be cleaned up if abandoned.
BTW, note that while Microsoft may have intended that objects which encapsulate unmanaged resources should clean them up if abandoned, there are some types of resources for which that really isn't practical. Consider an object that stores an object reference in a thread-static field, for example, and blanks out that object reference when it is Dispose'd (the disposal would, naturally, have to occur on the thread where the object was created). If the object gets abandoned but the thread still exists (e.g. in the threadpool), the target of the thread-static reference could easily be kept alive indefinitely. Even if there aren't any references to the abandoned object so its Finalize() method runs, it would be difficult for the abandoned object to locate and destroy the thread-static reference sitting in some thread.
What should go in 'if (disposing)'
All Managed objects should go inside if(disposing) clause. Managed objects should not go out side of it (which will be executed through the finalization).
The reason is that Garbage collectors finalization process can execute the Dispose(false) if that class has a Destructor. Normally there is a Destructor only if there are unmanaged resources.Garbage collector's finalization doesn't have a particular order to execute the Finalize method. So, other managed objects may not be in memory by the time finalization occurs.

C# memory and dispose related questions

I have the following piece of code, just wanted to check who will call the dispose? is it called automatically.
ToolTip toolTip = new ToolTip();
toolTip.SetToolTip(button, toolTipText);
Also let say I create a Timer local variable, who will call the dispose, what about memory leaks, as, if I call the dispose right away, the timer event, won't be fired.
Do I need to make sure that in the timer event handler dispose is called, even if I don't have any reference to the timer variable. Also do I need to unregister the event handler for that timer.
Edit:
But how to call dispose on ToolTip, if I call it won't show.
Also why I need to Dispose the Timer, if I don't have any reference.
And Do I need to also unregister the timer event handler?
Also does keeping a reference increases the class memory footprint.
ToolTip registers event handlers on the control on which it is shown. It's Hide() method is automatically called when the form's Deactivate event fires. Which will happen when the form is closed. That in turn ensures that its Windows handle is destroyed and event handlers are unregistered. After that there are no disposable objects left.
You can verify this for yourself with Reflector or the Reference Source. Relevant methods are, in order, BaseFormDeactivate, HideAllToolTips, Hide, ClearTopLevelControlEvents.
You don't have to call Dispose(), you don't have a leak.
Dispose is a method provided to allow you to release the object immediately. For example an exclusive file stream.
Finalize is a method that automatically releases any resources the object is using once it is no longer being used by your program.
You only need to worry about disposing when the object uses exclusive or finite resources. Examples being the file one, or a database connection. (Note that in both these cases Close is equivalent to disposing)
To answer your question, you are not disposing at all, but letting the finalizer run when it needs to.
In .NET the garbage collector will automatically free memory when an object can no longer be referenced from anywhere. When it does so, if the object has a finalizer it calls the finalizer. The finalizer is for cleaning up, usually unmanaged resources.
However, finalizers are expensive (they delay garbage collection on an object, for example) and you cannot tell when it will be run (as you can't tell when the GC will decide to collect it). They are usually left as a last resort for cleaning up things like unmanaged resources.
This is where the IDisposable interface and it's Dispose method comes in. Dispose can also be used to clean up, both managed and unmanaged resources. When you call the Dispose method it cleans up and the object is no longer in a stable, usable state.
If you have a resource which implements IDisposable you can call Dispose on it when you know you are done. That way and resources it is holding on to can be freed up as soon as possible. The usual way of doing this is to wrap it up in a using statement, which will automatically Dispose when the using block is done. e.g.:
using (SomeDisposableObject disposableObject = new SomeDisposableObject())
{
disposableObject.DoSomeStuff();
disposableObject.DoSomeMoreStuff();
}
When the using block is finished (after DoMoreStuff) Dispose is called on disposableObject. Using statements are a lot cleaner than the equivalent code when you take into account exception handling.
In the case of something like ToolTip, which has unmanaged references (a lot of WinForms in a wrapper around the unmanaged Win32 components) it will have a finalizer to make doubly sure the unamanged resources are freed correctly. However, if you call Dispose on the object, the cleanup code is run there and then and the finalizer is suppressed (it won't run when the object is collection by the GC).
So, to answer your question more directly, if you know exactly when an IDisposable is finished with it is a good idea to call Dispose. However, if you don't it is usually ok just to leave it up to the garbage collector to collect it and call the relevant code to correctly cleanup the object.
In the cases of ToolTip and Timer given, I wouldn't worry about calling Dispose on them yourself as I suspect it would be difficult to predict when they will be finished with.
You need to call Dispose on anything that implements IDisposable, or at least make sure something does. For UI components, add them to a form's Controls collection and they'll get disposed when the form closes. For other things you need to keep a reference to them and call dispose appropriately. It may be appropriate to make your class implement IDisposable just to call Dispose on your composed objects.
Generally, it's up to the object registering to an event to un-register - not doing so will create memory leaks. You should not rely on a Dispose method doing so.
Dispose is not called automatically, unless you wrap the object in a using() {} statement, or add it to the objects IContainer instance (if it's a designer class). If it's a class variable, you need to make the containing class implement IDisposable and dispose of the instance in it.

Categories

Resources