Solved

Is this bad? Creating object without assigning to a variable.

Posted on 2004-10-21
133 Views
Last Modified: 2010-04-23
I'm using this code to return a single value from a database.

strVar = New OleDbCommand("SELECT [FIELDNAME] FROM TBLNAME WHERE [CRITERIA]='123', oleCon).ExecuteScalar

This is a very fast, single-line-of-code method of getting what I want. If I were to do this with standard ADO.NET objects, then I'd have to declare a dataadapter, use it to fill a datatable, and then loop through datarows in the datatable just to get the first record returned so I could read from it. That's two to three more variables and a lot more code than one line.

So obviously, the method I'm using is more streamlined... and at this point you may be asking, "So what's the problem?"


Well... my only concern about this method is, I'm basically creating an object (the ole command) and returning one of its methods to a variable (strVar)... but I'm not returning the OBJECT itself to the variable, just its method. So my ole command gets created, but I don't have any control over it after the fact.


My question is... is this bad? Does this leave the oledbcommand object out in memory indefinitely (or until my app shuts down or whatever). Is this bad practice...? Should I be flogged for this? What are the ramifications here?



WATYF
0
Question by:WATYF
    16 Comments
     
    LVL 9

    Expert Comment

    by:Lacutah
    Best practice dictates that any time an object exposes a "dispose" method, then the object should be disposed of as soon as you are finished with it.  This allows the (automatic) garbage collection to release the orphaned object on its first iteration, instead of having to run more than once before the objects memory space is released.
    0
     
    LVL 9

    Expert Comment

    by:Lacutah
    As far as ramifications, not much as long as your program has sufficient idle time for the Garbage Collection to run (ie, it's not some 100% processor task that'll run for 30 minuites strait...)

    Of course, if you were going to do hundreds of iterations, I would recomend you change the CommandText for each iteration instead of creating a new object.
    0
     
    LVL 4

    Expert Comment

    by:eozz_2000
    Well... I think that is valid, when the framework detects that a variable has been discarded, calls the GarbageCollector of the framework and collects the memory discarded, is the same think to call the dispose method.

    This information came in the .net framework documentation.
    0
     
    LVL 9

    Accepted Solution

    by:
    It is not the same thing to call the dispose method.  Calling Dispose does NOT call Apllication-Wide (or even Object Wide) Garbage Collection.   The dispose method (implementing IDisposable.Dispose) is only made available in objects that need to do "extra" cleanup work before they can be fully released by the Garbage Collection process.  If you do not call Dispose on objects that implement the Dispose method, then in all likelyhood, the Garbage Collection process must run at least twice - once to call the objects Finalize Method, and again later (after the Finalize method has been called by the Garbage Collection- allowing the Object to release / Dispose of it's contained objects) so that the memory space of the object may be freed up.

    From .NET Framework Class Library, IDisposable Interface:
    The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used, however, it is unpredictable when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, and open files and streams.

    From .NET Framework Class Library, IDosposable.Dispose Method:
    "Use this method to close or release unmanaged resources such as files, streams, and handles held by an instance of the class that implements this interface. This method is, by convention, used for all tasks associated with freeing resources held by an object, or preparing an object for reuse.

    When implementing this method, objects must seek to ensure that all held resources are freed by propagating the call through the containment hierarchy. For example, if an object A allocates an object B, and object B allocates an object C, then A's Dispose implementation must call Dispose on B, which must in turn call Dispose on C. Objects must also call the Dispose method of their base class if the base class implements IDisposable.

    If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Dispose can throw an exception if an error occurs because a resource has already been freed and Dispose had not been called previously.

    A resource type might use a particular convention to denote an allocated state versus a freed state. An example of this is stream classes, which are traditionally thought of as open or closed. Classes that have such conventions might choose to implement a public method with a customized name, such as Close, which calls the Dispose method.

    Because the Dispose method must be called explicitly, objects that implement IDisposable must also implement a finalizer to handle freeing resources when Dispose is not called. By default, the garbage collector will automatically call an object's finalizer prior to reclaiming its memory. However, once the Dispose method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer. To prevent automatic finalization, Dispose implementations can call the GC.SuppressFinalize method.

    For more information on implementing finalizers, see the GC class and the Object.Finalize method."
    0
     
    LVL 4

    Expert Comment

    by:eozz_2000
    Wow... thanks for the information, I have read things that I have never heard before
    0
     
    LVL 3

    Expert Comment

    by:RacinRan
    and it seemed like such a simple question ... thanks for the compilation of info about the dispose method.

    0
     
    LVL 11

    Author Comment

    by:WATYF
    Well that's really informative... but I didn't see a concrete answer to my question in there. (I may have missed it, though.)

    Are you saying that the GC will collect the object immediately, since it wasn't returned to a variable...? If so, that's great... but I wasn't quite sure from what was being said if that was the case. Or do I need to create a variable for it, so I can call it's dispose method once I'm done with it?


    WATYF
    0
     
    LVL 4

    Assisted Solution

    by:eozz_2000
    Well... I think, the point of Lacutah is to explain that the objects that have the Dispose method must call this method, and the other not.

    If the object has the Dispose method, is better to create a new instance of the object, a variable and then call de method, if the object doesn'´t have that method you can create it like your code.
    0
     
    LVL 3

    Expert Comment

    by:RacinRan
    that's what I got out of it.
    0
     
    LVL 11

    Author Comment

    by:WATYF
    OK. That makes sense.

    Related to this,... usually I'll dispose of variables by setting them = to Nothing. Based on what he's saying, do I need to call the Dispose method before doing this?


    WATYF
    0
     
    LVL 9

    Expert Comment

    by:Lacutah
    That's what I meant, the implications are that youre using memory longer than necessary if you don't call the dispose method on the OleDbCommand object.

    If you're only doing it once, it's probably won't affect the speed / memory usage of the application noticably.  But it's best practice to call the dispose method whenever it's exposed by an object.

    On your related question, you should call the Dispose method if exposed THEN set the object reference to Nothing.  If you don't call dispose, then the Garbage Collection may have to run more than once before the memory space is released.    Setting the object reference to "Nothing" is prudent only if the object isn't out of scope in a timely manner - for example, the OleDbCommand object is declared in the Form that may remain open for 5 minutes, not in a Sub Procedure that takes < 1 second to run.   This will allow the Garbage Collection to rescue the object's memory space even if the parent object / method is unfinished.
    0
     
    LVL 6

    Assisted Solution

    by:The_Biochemist
    to the best of my knowledge the old COM archetecture utilised reference counting scheme (the number of current references to a particular object) to determine when an object went out of scope and actively removed the object from memory when it was no longer referenced (Deterministic finalization).

    However in the net all .NET world the garbase collector has no idea when an object comes out of scope as object reference counting no longer happens. Therefore even if you dispose an object it will not 'actively' get the garbage collector to remove it, rather the garbage collector randomly looks at all of the objects in memory and removes any of them which are no longer referenced. This process is done sporadically and is dependant on system resources - it is termed nondeterministic finalization.

    that said, relying on the garbage collector to remove your unwanted objects does mean that if your object still has an open system resource such as a socket it will not be released untill the object gets removed and on a system with lots of ram an resources that could be hours, days or potentially indefinate!

    Therfore:

    1) Add a dispose method to all of your objects and make sure it closes ALL of the objects open resources
    2) ALLWAYS call the dispose methods to ensure you don't accidentally leave an endlessly persisting open resource
    0
     
    LVL 11

    Author Comment

    by:WATYF
    Sorry for yet another follow up (I will increase the points)...


    So is setting a variable to Nothing right before a sub procedure ends a waste of time? Does the sub/function ending cause the var to = Nothing anyway?

    Usually I will use "= Nothing" at the end of a Sub to clean up the variables. Should I be using "Dispose" instead, and just forget using "= Nothing" at all? That would just be at the end of a Sub for a variable contained in the Sub, right? Based on what you're saying, if the var is part of an object that may remain open for a long time, you should dispose of it AND set it to Nothing once you're done with it.

    Is this correct?


    WATYF
    0
     
    LVL 6

    Expert Comment

    by:The_Biochemist
    To be honest you have one of 3 choices...

    1) You can leave the object alone and once it has gone out of scope it will eventually be removed

    2) You can set the object to nothing causing it to go out of scope and eventually be removed

    or

    3) You can call the dispose method (which you have altered to release all objects referenced by the object in question) causing it to go out of scope and eventually be removed

    essentially - whichever one you choose you have no control as to when the object will be removed. But (1) is very lazy, (2) is slightly less lazy and (3) is not lazy!
    0
     
    LVL 6

    Expert Comment

    by:The_Biochemist
    P.S to make my previous responce answer your original question...

    "My question is... is this bad? Does this leave the oledbcommand object out in memory indefinitely (or until my app shuts down or whatever). Is this bad practice...? Should I be flogged for this? What are the ramifications here?"

    It will have no effect as far as object removal goes because If an object goes out of scope it will be removed when the garbage collector gets round to it BUT it is not best practice.
    0
     
    LVL 11

    Author Comment

    by:WATYF
    sorry... forgot to follow up on this one.


    Thanks for all the info. I think I got what I need.


    WATYF
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Lean Six Sigma Project Manager Certification

    There are many schools of thought around successful project management, but few as highly regarded as the Six Sigma and Lean methods. With 37 hours of learning, this training will explain concrete processes for increasing efficiency and limiting wasted time and effort.

    Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
    Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
    With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…
    Hi everyone! This is Experts Exchange customer support.  This quick video will show you how to change your primary email address.  If you have any questions, then please Write a Comment below!

    856 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now