I have some Excel automation code that uses Excel COM objects. From other SO posts I know that one should do the following to release objects at the earliest convenience:
Excel.Range rng = GetSomeRange();
// do something with rng...
Marshal.ReleaseComObject(rng);
However, if I loop through cells in a range, is the following the correct procedure?
Excel.Range rng = GetSomeRange();
foreach (Excel.Range r in rng)
{
// do something with r
Marshal.ReleaseComObject(r); // release at earliest possible convenience
}
Marshal.ReleaseComObject(rng);
What I'm unsure of here is that if I release each r
in rng
and then I also release rng
am I effectively releasing rng
twice or correctly releasing additional references r
to rng
and rng
itself ?
Thanks in adv.!
EDIT
I went for the latter strategy:
Excel.Range rng = GetSomeRange();
foreach (Excel.Range r in rng)
{
// do something with r
Marshal.ReleaseComObject(r); // release at earliest possible convenience
}
Marshal.ReleaseComObject(rng);
which has reduced the memory significantly...
again - thanks to all!
Unfortunately, there is a lot of false information floating around. First let me state the answer clearly:
You do not have to call Marshal.ReleaseComObject
in most cases. Why? Because the Garbage Collector will do it for you.
* Note that I said most, you may find that holding onto to many references causes problems (for whatever reason). In those cases only, should you decide to call Marshal.ReleaseComObject
.
Kristofer, we’ve always had automatic releases for COM objects as the GC determines it needs to clean them up. They don’t get cleaned up immediately, but do get cleaned up at some point later after a GC or two. I've confirmed with this with the team.
They said:
In the type of app in the blog it doesn’t really matter, if people screw up their app will fail and they’ll get obvious ref-counting bugs. In cases where their code is being loaded inside of office, rather than the other way around, it is much more concerning because you can end up releasing someone else’s reference then there can be problems that they don’t notice in their code but breaks someone elses office add-in instead.
So, the point is that while ReleaseComObject is more deterministic, it's usually not necessary as the GC will do the same thing.
Also, I suggest you read Marshal.ReleaseComObject Considered Dangerous.
If you’re tempted to call “Marshal.ReleaseComObject”, can you be 100% certain that no other managed code still has access to the RCW? If the answer is ‘no’, then don’t call it. The safest (and sanest) advice is to avoid Marshal.ReleaseComObject entirely in a system where components can be re-used and versioned over time.
Now, maybe there is some reason you need to deterministically release those COM objects, but in most cases you can remove all those Marshal.ReleaseComObject
calls.