How VB.Net can screw up a newbie without them knowing it.
Posted on March 17, 2009
Filed Under Uncategorized
Let me preface this by saying I have no hate for VB.Net. When used properly, it is just as good as C#. However, VB as a whole has gotten a bad rep because generally the people that flock to it are the ones with no formal programming experience. Thus, they don’t really always know what they are doing. I’ve seen it a lot. I will also admit that I have done a lot of these horrendous things that I should have never done. In fact, this post is about something I did that turned out way bad when we fast forward a few years later (yes, it took that long for me to find this problem.)
Here is the problem and the solution I came up with over two years ago. We have a very large MDI application that has a lot of different forms. We didn’t want users opening up multiple copies of those forms, plus we wanted a neat way to bring certain forms to the foreground if they were already open.
My simple and what I thought was ingenious solution was to create a few functions that just check to see if the form is open… Something like this:
Public Function IsFormOpen(ByVal oFormName As Form) As Boolean Dim bAlreadyShown As Boolean = False Dim obj As Form For Each obj In Me.MdiChildren If obj.Name = oFormName.Name Then bAlreadyShown = True End If Next Return bAlreadyShown End Function
When I wrote that and it worked, it made sense to me that it would just pass in the type and I could get the name of the type and it would match and the world would be happy…
Now fast forward 2 years and we are getting some complaints of the application/whole computer being slow after running for a while. This smelled of memory leaks (which we have had lots of in the past). So I started doing my memory leak testing and now I am seeing all of our forms still being held open when they should be closed!
So turning off just my code debugging and putting a breakpoint in InitializeComponent() told me a big huge story. A story of how VB “helps” a developer by just doing things for them without them knowing. It seems that before going into the IsFormOpen function call, VB creates an object of that form type and passes in that object. That object never gets destroyed, either. Dispose on that object only gets called when the application exits. Nice, huh? So every time we open a form, we actually are creating two and only opening one. One simple change fixed it:
Public Function IsFormOpen(ByVal oFormName As System.Type) As Boolean Dim bAlreadyShown As Boolean = False Dim obj As Form For Each obj In Me.MdiChildren If obj.Name = oFormName.Name Then bAlreadyShown = True End If Next Return bAlreadyShown End Function
Incidentally, C# wouldn’t allow the first function to happen. It won’t even compile in any way, shape, or form (at least in the way I was trying to use it). It tells me the obvious, I was trying to use a Type as a variable. VB “helps” you with that…