Qual è la prassi migliore (o comunemente accettata) su dove dichiarare le variabili oggetto COM (scope) e come gestirne la pulizia quando si utilizza la gestione strutturata degli errori?
Ho appena trascorso un sacco di tempo a imparare sulla Garbage Collection e sul Conteggio di riferimento e mi occupo di rilasciare oggetti COM in .NET.
Lavorare con COM è fastidioso ...
Il dilemma
Mi rendo conto che è importante rilasciare oggetti COM referenziati dopo averli terminati. Mi rendo anche conto che è anche importante anticipare e gestire gli errori.
Queste due cose insieme sembrano essere in disaccordo con ciò che mi viene sempre battuto come best practice: dichiarare le tue variabili dove sono usate.
Ora, al fine di garantire che i riferimenti vengano rilasciati quando vengono eseguiti con essi, sembra che abbia più senso eseguire questa operazione di pulizia all'interno della porzione Finally
di un blocco Try / Catch.
Tuttavia, facendo ciò significa che non posso dichiarare queste variabili all'interno delle porzioni Try o Catch del blocco perché non saranno accessibili alla porzione Finally.
SO ....
Dove mi lascia in merito alle seguenti best practice?
Devo continuare a dichiarare le variabili all'inizio di ogni routine per pulirle usando Finally
?
C'è qualche altro metodo per accedere ai riferimenti COM alla fine di una procedura?
Sto solo raccogliendo pepe di merda per quanto riguarda le migliori pratiche?
Codice di esempio
Nell'Esempio 1, ho dichiarato tutte le mie variabili prima di entrare nel blocco Try / Catch. In questo modo posso assicurarmi che vengano puliti, indipendentemente da eventuali errori.
Nell'esempio 2, ho dichiarato le mie variabili dove sono utilizzate, ma ciò causa un problema con il potenziale non-rilascio di oggetti COM.
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