Iterating on Outlook COM objects - vsto

I have a doubt about when iterating over Outlook COM objects and whether I need always to release them or not.
What is the difference between below two for loops?
(suppose recipients is of type Outlook.Recipients)
foreach (Outlook.Recipient recipient in recipients)
{
// Do things here
// Release Outlook COM object (Is it necessary to release it?)
Marshal.ReleaseComObject(recipient);
}
for (int i = 1; i <= recipients.Count; i++)
{
// Do things here
Outlook.Recipient recipient = recipients[i];
// Release Outlook COM object (Is it necessary to release it?)
Marshal.ReleaseComObject(recipient);
}
And is it necessary to release Outlook.Recipient object in both cases?
I have heard that it is recommended that you rather use a for loop since a for-each might cause some unexpected behavior and your code to hang.
Using a foreach loop to loop through the Recipients collection automatically generates the enumerator behind the foreach statement that uses an internal COM object, which needs to be released.

Unless you are running into a specific problem, don't call Marshal.ReleaseComObject().
The first loop checks (at compile time) that the object implements _NewEnum property with the dispid of -4. At run-time, .Net reads that property and casts it to the IEnumVariant interface that is used to loop through the collection items. .Net run-time version of the enumerator tends to keep all accessed items referenced, so Marshal.ReleaseComObject won't have any effect until the loop exits and the enumerator is released.
The second one is just a good old for loop. Marshal.ReleaseComObject would work as expected.

There are two main ways for releasing underlying COM objects in .net based applications:
The first one is based on the garbage collector which swipes the heap and could also automatically release hanging objects. But to properly release COM objects you would need to call the GC twice:
GC.Collect
GC.WaitForPendingFinalizers
GC.Collect
GC.WaitForPendingFinalizers
Use the Marshal.ReleaseComObject method in the code to release underlying COM objects instantly in the code. I prefer using this way because it allows releasing objects where they were created and don't wait until GC finishes its work which is un-deterministically.
In that case the foreach loop is not recommended because it doesn't allow releasing COM objects that way. I always use an old approach with the for loop:
for (int i = 1; i <= recipients.Count; i++)
{
// Do things here
Outlook.Recipient recipient = recipients[i];
// Release Outlook COM object (Is it necessary to release it?)
Marshal.ReleaseComObject(recipient);
recipient = null;
}
Don't forget to set the source object to null.

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.

Destroy lua object by his method

I want to destroy class instance by its own method. For example:
obj = Object()
obj:destroy()
type(obj) == nil
Object is implemented on C. Is it possible?
If it's not possible, Second way is:
_G["obj"] = nil
collectgarbage()
Thanks!
I want to destroy class instance by its own method.
You should avoid this at all costs. Only expose an explicit destructor routine in Lua if you absolutely need to.
The correct way to handle this is to give your Lua C object a metatable with an __gc metamethod. This metamethod will be called right before Lua garbage collects the object.
If you absolutely must use an explicit destructor function (because you want the user to be able to release expensive resources immediately when they're done, without waiting for garbage collection), then you need to do two things:
Do not require the user to explicitly destroy the object. That is, the object should be able to be destroyed either via destructor or via garbage collection.
Do not break the object when it is explicitly destroyed. Every function that takes this object (member functions or free functions) needs to still work if the user called the explicit destruction function. Those functions may do nothing, which is fine. But the program shouldn't crash.
Basically, your object needs to still be in an "alive" state when it was explicitly destroyed. You need to have the object be a zombie: alive, but not very useful. That way, your program will still function even if it doesn't do the right thing.
Simple obj = nil in your example is enough. Note that you do not destroy content of object, you delete a reference that was in the variable obj, making real object somewhere in memory have one less reference and, if it reached 0 references, unreferenced an eligible for GC.
If your object doesn't have some external task to perform on destruction, that's pretty much all you need. Just lose all references by letting them go out of scope or overwriting variables/table members that contain those references with something else or nil. Otherwise you'd need to call object-specific destructor first and only then remove references.
It is not possible to make such a destructor automatically remove all references from everywhere, but at least it can clear object's internal state and set some internal flag that object is no longer usable or ready to be re-initialized.
It is possible, to some degree. You can create a subtable within the object as a private data store. That subtable is managed solely by the object and therefore can only have one reference. If you define a destructor method for the object, then it would delete the respective subtable, making it eligible for garbage collection. Of course, the parent table would still exist, leaving only the methods which do not occupy any significant resources.
Whether this is "good design" is subjective. I am merely offering a solution for the question asked.

Is it necessary to call Marshal.ReleaseComObject in C#4 when doing COM?

I have VS2010 and added a reference to a COM library to my project and VS embedded a primary interop inside the project.
If I reference objects from the COM library and I want to dispose of them quickly without waiting for the GC, is it needed to call ReleaseComObject ?
Marshal.ReleaseComObject provides a way to immediately drop references to this COM object from everywhere it is being consumed within managed code (because it releases the underlying IUnknown from the RCW that is holding it).
As Hans notes, the generally right course is to simply null your object allow the CLR and GC to do the COM object destruction at the appropriate time.
However, in situations where you need immediate action (COM object holds expensive/scarce resources, or perhaps during shutdown where the sequencing is very complex), calling ReleaseComObject can be the right thing to do.
Martyn
There are two types of approaches in terms of cleaning memory.
Reference Counting Algorithms
Garbage Collection
COM components use reference counting algorithm to reclaim memory. Whenever you do not need a reference of a com component you can call it. But Usually my approach is creating a virtual stack and deleting references like the source code below in C#. .NET guarantees as long as RCW is alive COM components is alive. When RCW is garbage collected release method is invoked. It is not necessary to call release in your code. But it does not effect gc cycles.
void DoSth
{
{
RunTimeCallableWrapper area for the code
ReleaseComObject
}
}

Difference Between Dispose And nothing

**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.

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).