Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Add the following before your call to xl.Quit():</p> <pre><code>GC.Collect(); GC.WaitForPendingFinalizers(); </code></pre> <p>You can also use <code>Marshal.FinalReleaseComObject()</code> in your NAR method instead of ReleaseComObject. <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx" rel="nofollow noreferrer">ReleaseComObject</a> decrements the reference count by 1 while <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject.aspx" rel="nofollow noreferrer">FinalReleaseComObject</a> releases all references so the count is 0.</p> <p>So your finally block would look like:</p> <pre><code>finally { GC.Collect(); GC.WaitForPendingFinalizers(); NAR(wSheet); if (wBook != null) wBook.Close(false, m_objOpt, m_objOpt); NAR(wBook); xl.Quit(); NAR(xl); } </code></pre> <p>Updated NAR method:</p> <pre><code>private void NAR(object o) { try { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o); } catch { } finally { o = null; } } </code></pre> <p>I had researched this awhile ago and in examples I found usually the GC related calls were at the end after closing the app. However, there's an MVP (Mike Rosenblum) that mentions that it ought to be called in the beginning. I've tried both ways and they've worked. I also tried it without the WaitForPendingFinalizers and it worked although it shouldn't hurt anything. YMMV.</p> <p>Here are the relevant links by the MVP I mentioned (they're in VB but it's not that different):</p> <ul> <li><a href="http://www.xtremevbtalk.com/showthread.php?p=1157109#post1157109" rel="nofollow noreferrer">http://www.xtremevbtalk.com/showthread.php?p=1157109#post1157109</a></li> <li><a href="http://www.xtremevbtalk.com/showthread.php?s=bcdea222412c5cbfa7f02cfaf8f7b33f&amp;p=1156479#post1156479" rel="nofollow noreferrer">http://www.xtremevbtalk.com/showthread.php?s=bcdea222412c5cbfa7f02cfaf8f7b33f&amp;p=1156479#post1156479</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. COUsing the garbage collector in this way should not be necessary. I have an extremely complex Office automation system written in .NET and I will admit that in one case I did have to resort to doing this, but for any small-to-medium project you ought to be able to clean up the COM references so that it's not necessary. Note that if you do use this method, you need to do the Collect/Wait twice, since the first iteration simply marks stuff as available for collection.
      singulars
    2. COHi Gary, I agree that you do not *have* to do it this way, but as a practical matter I find that it is too easy to miss one (or more) explicit Marshal.FinalReleaseCom() object calls and then you will hang. Finding your error in a medium to large scale project can be next to impossible. (Neither the compiler nor the code analysis tools will help you.) So I find it far safer to use the "final cleanup" approach.
      singulars
    3. COGary, you do not have to call GC.Collect() and GC.WaitForPendingFinalizers() twice. What happens is, when you call GC.Collect() the finalizers for the RCWs are all called, which decrements the COM reference count and releases the reference on the COM side of the fence (which is all you care about here). The RCW itself, however, will remain uncollected until the NEXT garbage collection. But we don't care about that -- the RCW has already dropped it's payload. (If one is using VSTO, however, you DO have to call Collect/Wait twice, because VSTO uses an additional layer of finalizers.)
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload