-3

foreach loops call .dispose() on objects which implement IDisposable automatically. It's a nice feature, but let's say you had the following function:

public COMWrapper GetCOMWrapperByName(string COMWrapperName)
{
    List<COMWrapper> COMWrapperList = GetCOMWrappersFromPlace();

    foreach(COMWrapper cw in COMWrapperList)
    {
        if(cw.name == COMWrapperName)
            return cs;
    }
}

And that COMWrapper's .dispose() method released it's associated COM Object.

As I understand it, the foreach loop would dispose of each COMWrapper at the end of the loop, but then leave the matched COMWrapper since it was returned before reaching the end of the statement.

This becomes a problem, however, for the COMWrapper references left in the COMWrapperList list, as half of them have had their underlaying COM Object RCW wrappers removed without themselves being disposed of. Worse, the REMAINING half of the list has totally unmanaged COM Objects now floating in the ether, and since the COMWrapper objects they exist in haven't been disposed of, it becomes very difficult to traverse the List and call .dispose() appropriately in a finally statement (we don't, after all, want to release COM Objects twice).

Is it possible to determine if a COM Object has been released without catching a ObjectDisposedException exception? Is there a better way to dispose of the remaining COM Objects and their wrappers? Or maybe I'm absolutely misreading this situation and need to reevaluate my base understanding of COM Objects, what am I doing wrong?

Sandy Gifford
  • 7,219
  • 3
  • 35
  • 65
  • 2
    `foreach loops call .dispose() on objects which implement IDisposable automaticall` No it doesn't. – Servy Sep 22 '14 at 18:07
  • I believe it does ([Link](http://stackoverflow.com/questions/4982396/does-foreach-automatically-call-dispose)) – Sandy Gifford Sep 22 '14 at 18:08
  • Ah, I see your answer now – Sandy Gifford Sep 22 '14 at 18:09
  • @SandyGifford the _enumerator_ will be disposed, not each object in the collection. – D Stanley Sep 22 '14 at 18:09
  • You need to read the link more carefully, as it does not say what you claim it says. – Servy Sep 22 '14 at 18:09
  • @Servy I see that now, sorry for the misunderstanding – Sandy Gifford Sep 22 '14 at 18:11
  • Really, though? -1? I get that I misread something, but it doesn't seem to be an entirely unbelievable misunderstanding, and in fact lead to a possibly useful future answer. – Sandy Gifford Sep 22 '14 at 18:12
  • @DStanley yup, I feel silly for missing that one, makes sense now. Thanks! – Sandy Gifford Sep 22 '14 at 18:13
  • RCWs do not implement IDisposable. They are managed by the GC just like any .NET object, it is simply more obvious in the case of COM objects. If you absolutely need to release them then GC.Collect() gets the job done. Not a weapon you should ever grab lightly, just let the GC get to it at its own pace. – Hans Passant Sep 22 '14 at 18:14
  • @HansPassant I should have specified; the `COMWrapper` objects here are supposed to represent custom written classes (by me) that wrap around COM Objects (so that I can use nifty little things like `using`). Thanks for your input, though! – Sandy Gifford Sep 22 '14 at 18:17
  • @HansPassant I did mention that the `COMWrapper` class had a `.dispose()` method, and implied (although, I admit, never actually stated outright) that it was a wrapper for a COM Object; however, since this question was already answered, if you would like to continue this conversation (I wouldn't mind, as I obviously have a lot to learn) it would probably be best to do so in chat. – Sandy Gifford Sep 22 '14 at 18:24

1 Answers1

5

foreach doesn't dispose of all of the objects in the sequence being iterated. It only disposes of the IEnumerator object that provides you with the objects being iterated over.

Servy
  • 202,030
  • 26
  • 332
  • 449