views:

207

answers:

7

I was reading about the Form's events in VB6 such as "Unload" "QueryUnload" and "Terminate", and about the "End" statement: http://articles.techrepublic.com.com/5100-10878%5F11-5533338.html http://visualbasic.freetutes.com/learn-vb6-advanced/lesson6/p5.html

I used to have problems with a VB6 app (it calls a lot of windows' apis). When I "End" in the main form's Unload event, it crashed the entire IDE! When I carefully closed all connections, stopped my timer, set to nothing all forms, and after all that cleaning process, place the "End" at the very last line in the main form's Terminate event everything went ok. Not more crashing :)

My question is about if it is necesssary to do all this "cleanning process" in .Net environment. I know that there's the Garbage Collector that erase all remaining bits that can cause problems.

Or, it doesn't matter if it is VB6 or .Net, it is a good practice to clean everything before "Ending" your app?

+7  A: 

No need.

Unless you are referencing COM or GDI+ related or unmanaged component or the resources you are using, then you have to manually dispose the reference at the Dispose method.

See here for more reference.

Ngu Soon Hui
A more up-to-date reference for the current version of .NET: http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx
TLiebe
Thanks Tliebe, I've updated the link
Ngu Soon Hui
It is suggested to dispose any resources related to GDI+ like a Brush, a Pen or even an Image.
Pierre-Alain Vigeant
Thanks a lot for the link! :D
yelinna
An additional guideline. If you are referencing an object that implements IDisposable, then you should ensure its Dispose method is called when you've finished with it. The obvious technique for local variables is to use `Using`. If you have a field that references an IDisposable object, you may need to implement IDisposable yourself.
MarkJ
+1  A: 

.NET applications are good at cleaning up memory that they've used. However, you still need to make sure you close any resources you are using (e.g. files, database connections, etc.). They will be cleaned up when the program exits but it's always good practice to clean them up in your code as soon as they aren't needed anymore.

TLiebe
A: 

The biggest concern with .NET is to clear un-managed resources. When your application exits the others should be ok. But personally I'd recommend reading up on .NET Garbage Collection a bit from the MSDN documentation just so you are a bit more familiar with it.

Mitchel Sellers
+3  A: 

I think best approach is: if class implement IDisposable, then you should use using statement. Example:

using(SomeDisposableClass instance = new SomeDisposableClass())
{
    // do stuff;
}

or, in VB.NET

Using instance As Stream = New SomeDisposableClass 
    '' Do stuff
End Using

When your code leaves that using block, SomeDisposableClass will free up their resources.

Rubens Farias
The sample code is C#. To make it VB.Net just remove the curly braces and semicolon, remove the explicit typing of `SomeDisposableClass`, and turn the `//` comment into a `!` comment. C# is so wordy :)
MarkJ
This is the best approach for local variables, but you also need to know what to do about fields. See Mike's answer http://stackoverflow.com/questions/1595118/is-it-necessary-to-free-the-memory-in-net-as-if-in-vb6/1595233#1595233
MarkJ
+2  A: 

The golden rule: in .NET, you do not need to explicitly release a resource unless it is unmanaged, or it uses unmanaged resources.

Now, the trick is figuring out whether or not a resource uses unmanaged resources. If a component implements the IDisposable interface, it uses an unmanaged resource, and you need to explicitly release it by invoking its Dispose method. The caveat here is that some objects are sneaky, and expose different methods that are more intuitive (like the DataReader's Close method, which essentially disposes the object).

Nonetheless, if an object implements IDisposable, you should invoke its Dispose method as soon as you are finished working with it. If the object is a class-level variable, your class should implement IDisposable, and your implmentation of Dispose should dispose of your reference to the object.

For more information see Implementing Finalize and Dispose to Clean Up Unmanaged Resources on MSDN.

Mike Hofer
+1  A: 

Automatic garbage collection is a blessing.

I remember an application I made in VB5 in which I decided to use the pseudo-objects it provided. I don't remember why but there was a point in which a large amount of objects previously created were no longer needed, so at first I tried to release them all at once. Result: the application freezed for several seconds! I resorted to hold the dirty objects in a list, and release them one at a time by using a timer.

I admit that there was probably bad design on my side, but anyway in .NET I wouldn't have had the same problem.

Konamiman
It is good to know these things not just happen to me :)
yelinna
The down vote is for the bad design, or for using VB5?
Konamiman
Different problem - your application wasn't mysteriously crashing. It was predictably freezing when it did some intensive work. I think Microsoft would say "this behavior is by design".
MarkJ
I just wanted to tell my personal experience with VB5 memory management, I have never pretended that it was the same problem. Anyway I admit that my answer was somewhat out of topic.
Konamiman
.NET's garbage collection essentially keeps the list and the timer for you. You might still find your app freezes while it tidies up (you still need to make a design mistake - same as in VB6)
MarkJ
+2  A: 

There's no need to do obsessive cleaning in VB.Net or in VB6.

I have nothing to add to the good answers about VB.Net's garbage collection, and do use Using if the object in question implements IDisposable.

But I will say this: it is pretty similar in VB6. There's no need to set forms or other variables to Nothing or to use End. API calls in VB6 are the equivalent of unmanaged code in VB.Net - both need extreme care, especially in releasing resources. I would guess that it was your API calls causing the crash.

Another culprit may have been the evil End statement. End is deprecated in the VB6 manual precisely because it suppresses cleanup events like Form_Unload. Your tidy-up code (setting to Nothing) might have caused your termination events like Form_Unload and Class_Terminate to fire. Perhaps the event handlers then cleaned up the API calls properly? If you had just avoided using End, the event handlers would have fired, and it might not have been necessary to set the variables to Nothing. Here's an excerpt from the VB6 manual End topic:

Note The End statement stops code execution abruptly. Code you have placed in the Unload, QueryUnload, and Terminate events of forms and class modules is not executed...

The End statement provides a way to force your program to halt. For normal termination of a Visual Basic program, you should unload all forms.

MarkJ
You're right, "End" is evil. More evil than "Go To". In a web page they say that using "End" is like stopping a train with a wall of bricks.
yelinna