Difference Between Dispose And nothing - vb.net

**Public Sub ExecuteQuery(ByVal pQueryString As String, Optional ByVal pConn As Odbc.OdbcConnection = Nothing)
Dim Mycmd As New Odbc.OdbcCommand(pQueryString, MyConn)
Mycmd.ExecuteNonQuery()
Mycmd.Dispose()
End Sub**
Here I am Clear the object using Dispose( Mycmd.Dispose()). Can I Use here Nothing ( Mycmd = Nothing? . Which is the Best ?
Please Help Me Sir,
By
Arul.

Dim Mycmd As New Odbc.OdbcCommand(pQueryString, MyConn)
This command stores the reference of object created by New Odbc.OdbcCommand(pQueryString, MyConn) into Mycmd, i.e Mycmd would basically have the address of the newly created object.
now when you do
Mycmd.Dispose()
then it indicates that the use of that newly created object is over and the space allocated to that object can be freed during garbage collection.
but when you do
Set Mycmd = Nothing
then it just remove the reference of the newly created object from Mycmd, it does not mark it for garbage collection.

Oftentimes, .net objects will ask other entities (which may or may not even be on the same computer) to "do something"(*) on their behalf, and such entities will continue doing so unless or until they are told to stop. Such objects should implement IDisposable, and their IDisposable.Dispose routine should notify any and all entities which had been doing something on their behalf, to stop doing so. If all references to an IDisposable object were to disappear without Dispose being called first, some other entities might continue forever in uselessly doing something on behalf of an object which has long since ceased to exist.
(*) That "doing something" could be anything, including blocking other requests to do something. For example, an object might ask the operating system for exclusive access to a file, and the operating system might relay that request to another computer. If the object doesn't notify the OS when it no longer needs access to the file, the server could leave everyone else in the universe locked out of the file indefinitely.
In an effort to minimize problems from entities' perpetually acting on behalf of abandoned objects, .net provides a means by which objects can ask to be notified when they're abandoned. If an object which overrides Object.Finalize() is abandoned, then .net will usually call that object's override of the Finalize() method. This kinda sorta works, mostly, but it should almost never be relied upon. It's very hard to design a class so that Finalize() will always do the right thing and never do the wrong thing. Among other things, if one isn't careful, it's possible for .net to call Finalize() on an object which it determines is going to be abandoned, even while that object is interacting with an outside entity. This will never happen in code which properly calls Dispose on the object, but may happen in code which relies upon Finalize().

If you mean assigning the value Nothing to the object as below:
Set Mycmd = Nothing
This doesn't actually do anything in terms of signaling as object ready for garbage collection, or freeing an object's used resources.
In VB6 setting an object to equal Nothing was the correct way to free the object's resources, but now calling the Dispose method is correct. Where objects do not implement IDisposable, then you can simply leave them.
Garbage collection will then happen in its own time (and would have even without the call to .Dispose() ).

There is not any .nothing() method to release object resource. You can use dispose and nothing to release object resources. But dispose is used when IDisposable interface is implemented. If you are using your custom classes. The .net built in object already has this functionality but it works if your object is having referenced otherwise it will give an error. You can use
command=nothing
for all objects either .net framework or custom. Both release object.

Related

Is it expensive to connect to COM objects?

I'm actually involved into a legacy system maintenance that has been written in PowerBuilder.
My actual objective is to handle the errors that may occur when connecting to COM objects.
The COM objects have been written in VB.NET and are mainly Web services.
I have defined a base factory which handles the instantiation of the COM objects through the PB function ConnectToNewObject().
So, when I instantiate a COM object, I get an instance of an oleobject.
In the code to be replaced, I can see that the oleobject used may be immediately destroyed. In some other places, it isn't. To add to the confusion, sometimes it is previously disconnected.
So I can encounter either:
oleobject lole_new_com_object
lole_new_com_object = create oleobject
lole_new_com_object.ConnectToNewObject("MyAssembly.MyNamespace.MyClass")
...
lole_new_com_object.DisconnectObject() // Disconnect before destroy...
destroy lole_new_com_object
or:
oleobject lole_new_com_object
lole_new_com_object = create oleobject
lole_new_com_object.ConnectToNewObject("MyAssembly.MyNamespace.MyClass")
...
// No disconnect...
destroy lole_new_com_object
So I wonder whether it is expensieve to instantiate an object this way.
Would it be best to disconnect before any destroy?
Would it be best to destroy any unreturned oleobject?
Would it be best to define them as singletons?
I am quite comfortable in PowerBuilder, though I am no expert. For such concerns, I don't know how PB handles things.
From the official documentation here: Shutting down and disconnecting from the server
You can rely on garbage collection to destroy the OLEObject variable.
Destroying the variable automatically disconnects from the server.
It is preferable to use garbage collection to destroy objects, but if
you want to release the memory used by the variable immediately and
you know that it is not being used by another part of the application,
you can explicitly disconnect and destroy the OLEObject variable
So you can keep the destroy w/o the disconnect. As for the destroy itself, it depends on the type of object. You don't have to do it, especially for in-process objects. Usually, it's used for COM objects such as Microsoft Word or Excel (when you want to make sure the exe is really gone when you want it to be gone).
You should disconnect before the destroy and destroy any which have been created.
I don't know if defining them as singletons would make any difference or not.
I agree with Matt's comment. Theoretically a local variable is automatically destroyed when the script ends. That being said, I think most developers would code a destroy immediately after the DisconnectObject like in your first example.

VB.NET Track COM RCW error

I have a really big project that I can not easily strip down.
When the application is being closed, I get the error
"InvalidComObjectException: A COM object that has been disconnected from the RCW can not be used."
Details:
System.Runtime.InteropServices.InvalidComObjectException has occured.
HResult=-2146233049
Message=A COM object that has been disconnected from its RCW can not be used.
Source=mscorlib
StackTrace:
at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis)
InnerException:
Unfortunately I can not see what COM object this is about.
Does anybody know how I can find that out? Unfortunately I can't read ASM to analyze the disassembly.
There are some steps you could try and since you haven't posted any code I will try to enumerate some of the most common key factors...
First, there is no order when disposing objects. If a close/dispose/finalize action is invoked, object C might be disposed before object A and if some object is still alive it might try to access an already disposed object.
Second, beware of events. It's very common to get errors about accessing a disposed object originated from an event call.
Third, do not dispose objects inside an event scope nor destructors. Create your own method to free your object(s).
Since you don't know which COM object is the culprit, I suggest you look for the ones that you do close, dispose, disconnect, etc...
You might want to read this blog in order to better understand how RCW's work and also to help you with your problem.
Edit:
After reading your comment, I felt I should add two possible causes:
If after removing Microsoft.VisualBasic runtime methods you've solved your problem, then I suspect that inside one, or more, of those methods you have incremented the count of a reference to one, or more, of your COM(s) and did not release properly.
Be sure to ReleaseComObject checking the reference count until it's 0 and then set it to nothing(VB) or null(C#) and let the Garbage Collector do the rest.
The other option is that one of those methods tried to access an already disposed reference to a COM object, resulting in a RCW error, since is no longer callable.
As a final comment, after releasing the COM object always set it to nothing or null, this will release the reference to the variable and you can always check it's availability anywhere in the code.

Using Keyword: .Close or .Dispose

When implementing the using keyword to instantiate an IO.StreamWriter object does that imply that .close is called on the object or .dispose? Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
The using keyword will call Dispose. However, by convention, Dispose and Close should always perform the exact same functionality, and be interchangable.
As such, any resource that is IDisposable but also provides a Close() method, such as Stream derived classes, are fine to use within a using block.
This is addressed in the Framework Design Guidelines explicitly: "it is important that you make the Close implementation identical to Dispose"...
The MSDN help for IDisposable also suggests this: "The implementer of a class that has such a convention might choose to implement a public method with a customized name, such as Close, that calls the Dispose method."
Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
It will not be garbage collected - after it is no longer in scope, and no longer referenced by any objects, it will be eligible for garbage collection. This means that it will (at least if written properly), eventually get cleaned up, but it may not happen for a long time - including not until the program terminates. The using block causes the resource (not the memory), such as the stream, to be closed immediately.
Using only calls Dispose at the end of the scope. However, for classes such as StreamWriter, Dispose ends up calling Close internally.
Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
This is a misconception: the whole reason for the Using block and the Dispose method is that an object is not garbage collected immediately at the end of the scope.

Does assigning to Nothing cause Dispose to be invoked?

I recently saw some VB .NET code as follows:
Dim service = ...
Try
...
service.Close()
Finally
service = Nothing
End Try
Does assigning Nothing to service do anything? If it is a garbage collection issue, I am assuming that when "service" went out of scope the referenced object would be garbage collected and the dispose method called on the object.
It seems to me that assigning this variable Nothing can't really do anything, as there could be another reference to the object around so the reference counts haev to be checked anyways.
It only releases the reference, which may mean that the object is available for garbage collection (there could still be other variables referencing the same object). If the object implements IDisposable, you need to call Dispose explicitly, otherwise you may have a resource leak.
NO!
You're seeing old VB6 code, where assigning Nothing reduced the reference count on COM objects.
In most situations assigning null (Nothing) to a reference makes no difference to garbage collection what so ever.
The garbage collector doesn't care about scope, it only cares about usage. After the point in the code where the object is used the last time, the garbage collector knows that it can collect it because it won't be used any more.
Assigning null to the reference doesn't count as using the object, so the last point of usage is before that code. That means that when you clear the reference the garbage collector may already have collected the object.
(In debug mode though the usage of a variable is expanded to it's scope, so that the debugger can show the value of the variable throughout it's scope.)
Assinging NULL to a reference in .NET does not help to clean the object away. It might help the garbage collector to run a little quicker in some corner cases but that's not important at all. It does not call dispose, either (when dealing with a disposable)
I love to assign NULL anyways to explicitly state that I won't use that other object anymore. So it has much more to do with catching bugs (you'll get a nullreference exception instead of possibly calling into some other object - which might fail or even silently create some side effects.)
So assigning NULL after closing another object (File or whatever) is a "code cleanliness" thing that eases debugging, it's not a help to the garbage collector (except in some really strange corner cases - but when you need to care about that you WILL know more about the garbage collector than you ever wanted to know anyways ...)
As everybody has already said, setting to nothing does not force garbage collection, if you want to force GC then you would be far better to use the using ke word
Using objA As A = New A()
objA.DoSomething()
End Using
You still don't need to set to nothing as the End Using tells the Garbage collection that the object is no longer to be used
It's important to understand in .net (or Java) that a variable, field, or other storage location of class type Foo doesn't hold a Foo. It holds a reference to a Foo. Likewise, a List<Foo> doesn't hold Foos; it holds references to Foos. In many cases, a variable will be known by the programmer to hold the only extant reference to some particular Foo. Unfortunately, the compiler has no general means of knowing whether a storage location holds the only extant reference to an object, or whether it holds one of many.
The main rule about IDisposable is that objects which implements IDisposable should be told they are no longer need sometime between the moment they are in fact no longer needed, and the time that all references to them are abandoned. If an object hasn't been Disposed, and code is about to overwrite the only extant reference to it (either by storing null, or by storing a reference to something else), the object should have its Dispose method called. If there exist other reference to the object, and the holders of those references expect to keep using it, Dispose should not be called. Since the compiler can't tell which situation applies, it doesn't call Dispose but leaves that to the programmer (who hopefully has a better idea of whether or not to call it).

Is there a need to set Objects to Nothing

I always read that it is recommended to set objects to nothing, once I am done with them. But I normally use them only in functions inside forms.
Isn't the reference lost and memory released when the function scope is left, regardless of setting objects to Nothing?
i.e. is it really necessary to do:
Set db = Nothing
Set record_set = Nothing
VB uses a so-called "reference counting" garbage collector.
Basically, the moment a variable goes out of scope, the reference counter on the referenced object is decremented. When you assign the object reference to another variable, the reference counter is incremented.
When the counter reaches zero, the object is ready for garbage collection. The object resources will be released as soon as this happens. A function local variable will most likely reference an object whose reference count never goes higher than 1, so object resources will be released when the function ends.
Setting a variable to Nothing is the way to decrease the the reference counter explicitly.
For example, you read in a file, and set the file object variable to Nothing right after the ReadAll() call. The file handle will be released immediately, you can take your time process its contents.
If you don't set to Nothing, the file handle might be open longer than absolutely necessary.
If you are not in a "must unblock valuable resource" kind of situation, simply letting the variables go out of scope is okay.
Garbage collection is rarely perfect. Even in .NET there are times where you are strongly encouraged to prompt the system to do garbage collection early.
For this reason, I explicitly both close and set to Nothing recordsets when I'm done with them.
The very last line of the help topic for "Recordset.Close" in the Microsoft DAO help and the Access Developer Reference is this:
"An alternative to the Close method is
to set the value of an object variable
to Nothing (Set dbsTemp = Nothing)."
http://msdn.microsoft.com/en-us/library/bb243098.aspx
With that in mind, this article from the Microsoft Knowledge Base entitled "How to prevent database bloat after you use Data Access Objects (DAO)", tells you that you should explicitly close if you don't want your databases to bloat. You'll notice that the article is a little vague about the details; the "Cause" section is unclear, almost to the point of being gibberish.
http://support.microsoft.com/kb/289562
SYMPTOMS: A Microsoft Access database
has begun to bloat (or grow rapidly in
size) after you implement Data Access
Objects (DAO) to open a recordset.
CAUSE: If you do not release a
recordset's memory each time that you
loop through the recordset code, DAO
may recompile, using more memory and
increasing the size of the database.
MORE INFORMATION: When you create a
Recordset (or a QueryDef) object in
code, explicitly close the object when
you are finished. Microsoft Access
automatically closes Recordset and
QueryDef objects under most
circumstances. However, if you
explicitly close the object in your
code, you can avoid occasional
instances when the object remains
open.
Finally, let me add that I have been working with Access databases for 15 years, and I almost always let my locally declared recordset variables go out of scope without explicitly using the Close method. I have not done any testing on it, but it does not seem to matter.
When you are using ASP classic (server-side scripting), it is important to set all objects to nothing when you are through with them, because they do not go out of scope until the [virtual] server is shut down.
For this reason, all MS VB scripting examples always showed objects being closed and set to nothing. So that the script excerpts could be used in environments like ASP classic where the objects did not go out of scope.
There are, rarely, other situations where you wish to code long-running processes where the objects do not go out of scope, and you find yourself running out of physical memory if you do not explicitly release objects.
If you find yourself coding ASP classic, or running processes in global scope for some other reason, then yes, you should explicitly release objects.
References are supposed to be cleaned up when the variable goes out of scope. Presumably this has improved with later versions of the software, but it was at one time not reliable. I believe that it remains a good practice to explicitly set variables to "Nothing."
I usually always put this at the end of my procedures, or call a "CloseRecordSet" sub with it in if I'm using module level ones:
Private Sub Rawr()
On Error GoTo ErrorHandler
'Procedural Code Here.
ExitPoint:
'Closes and Destroys RecordSet Objects.
If Not Recset Is Nothing Then
If Recset.State = 1 Then
Recset.Close
Conn.Close
End If
Set Recset = Nothing
Set Conn = Nothing
End If
Exit Sub
ErrorHandler:
'Error Handling / Reporting Here.
Resume ExitPoint
End Sub
That way however the procedure ends, (be it normally or due to an error) the objects are cleaned up and resources are free.
Doing it that way is quite safe in that it you can just slap it in and it will only do what is necessary in regards to closing, or destroying the recordset / connection object, incase it has already been closed (due to a runtime error or just closing it early as ya should, this just makes sure).
Its really not much hassle and its always best to clean up your objects when you're finished with them to free up resources immediately regardless of what happens in the program.
Try this
If Not IsEmpty(vMyVariant) Then
Erase vMyVariant
vMyVariant = Empty
End If