What is best (or commonly accepted) practice for where to declare COM object variables (scope) and how to handle cleaning them up when using structured error handling?
I just spend a whole load of time learning about Garbage Collection and Reference Counting and dealing with releasing COM objects in .NET.
Working with COM is annoying...
I realize it's important to release referenced COM objects after finishing with them. I also realize it's also important to anticipate and handle errors.
These two things together seem to be at odds with what keeps getting beaten into my head as best practice: declaring your variables where they are used.
Now, in order to ensure the references are released when done with them, it seems to make the most sense to do this cleanup within the
Finally portion of a Try/Catch block.
However, doing so means that I cannot declare these variables within the Try or Catch portions of the block because they will not be accessible to the Finally portion.
Where does that leave me with regards to following best practices?
Should I continue to declare variables at the beginning of each routine in order to clean them up using
Is there some other method of accessing COM references at the end of a procedure?
Am I just picking pepper out of fly shit with regards to best practices?
In Example 1, I've declared all my variables before entering the Try/Catch block. This way I can ensure they get cleaned up, regardless of any errors.
In Example 2, I've declared my variables where they are used, but this causes a problem with potential non-release of COM objects.
Imports System.Runtime.InteropServices Module COMexamples Sub Example1() Dim Com1 As SomeCOM Dim Com2 As AnotherCOM Try Com1 = New SomeCOM Com1.DoSomeStuff() Catch ex As Exception Com2 = New AnotherCOM Com2.CleanupTheMess() Finally If Not Com1 Is Nothing Then Com1.Close() Marshal.FinalReleaseComObject(Com1) End If If Not Com2 Is Nothing Then Com2.Quit() Marshal.FinalReleaseComObject(Com2) End If End Try End Sub Sub Example2() Try Dim Com1 As New SomeCOM Com1.DoSomeStuff() 'If an exception is thrown, the object won't get released! Com1.Close() Marshal.FinalReleaseComObject(Com1) Catch ex As Exception Dim Com2 As New AnotherCOM Com2.CleanupTheMess() 'Another exception here means we miss releasing this COM reference too! Com2.Quit() Marshal.FinalReleaseComObject(Com2) Finally 'This is pretty much useless now as Com1 and Com2 are out of scope here End Try End Sub End Module