This post is the second in my series on getting your head around COM Interop. My aim here is not to teach you all the innards of COM Interop, but instead to communicate a few key principles. These principles will (hopefully) make your life a little simpler when coding in .NET against COM components (particularly in relation to getting the COM objects to clean themselves up).
COM Interop Principle #1: Don’t Cheat (by relying on the Garbage Collector)
In my previous post, I listed a short code sample that was not behaving as I might have liked. Specifically, it was not closing down Excel when I wanted it to. In that post I called for attempts to get the code ‘working’ without calls to GC.Collect().
But, what if you ignored my requirement to not use GC.Collect()? Well, you would likely have come up with a solution something like this:
Option Strict Off
Option Explicit On
Imports msE = Microsoft.Office.Interop.Excel
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim wb As msE.Workbook
Dim ws As msE.Worksheet
Dim xlApp As msE.Application
'==========================
xlApp = New msE.Application
xlApp.DisplayAlerts = False
xlApp.Interactive = False
xlApp.Workbooks.Add()
wb = xlApp.Workbooks(1)
'Clear all but the first worksheet
For Each wrk As msE.Worksheet In wb.Worksheets
If wrk.Index > 1 Then wrk.Delete()
Next
ws = wb.Sheets(1)
xlApp.Visible = True
Threading.Thread.Sleep(5000) 'So we can see Excel
wb.Close(False)
xlApp.Quit()
Marshal.ReleaseComObject(ws)
Marshal.ReleaseComObject(wb)
Marshal.ReleaseComObject(xlApp)
GC.Collect()
GC.Collect()' A couple more for good measure
GC.Collect()' A couple more for good measure
GC.WaitForPendingFinalizers()
End Sub
End Class
So, what is the problem?
There are two:
- It doesn’t work (well, not on my machines running Visual Studio 2008 on Vista 32-bit, nor my machines running Visual Studio 2003 on XP 32-bit).
- Even if it did work on your PC (or in your version of the .Net Framework) there is no guarantee that it would work in the future or on other machines.
So:
COM Interop Principle #1: Don’t Cheat (by relying on the Garbage Collector)
As with all principles, there are exceptions! Such as:
- If the lifetime of your RCWs (COM components) is the same as your application (eg you will be loading Excel when your application starts, and closing it when your application closes) then there is little point in cleaning up correctly. You can be confident (not 100% sure, but confident) that all RCWs will be cleaned up when your process shuts down. So, cheating is OK.
Coming up next – COM Interop Principle #2: Fear the Period.
[...] week’s post was about what not to do when dealing with COM [...]
Pingback by COM Interop Principle #2 - Fear the Period « Matthew Wills @ Readify — May 26, 2008 @ 12:37 pm