IDisposable и COM - PullRequest
       5

IDisposable и COM

1 голос
/ 26 февраля 2010

Поскольку COM-объекты хранят ресурсы, не связанные с памятью, но не поддерживают IDisposable, я опробую некоторые идеи, чтобы подделать их. Что вы думаете о моей первой попытке?

Public Function ComBlock(ByVal ParamArray comObjects As Object()) As IDisposable
    For i As Integer = 0 To comObjects.Length - 1
        If comObjects(i) Is Nothing Then Throw New ArgumentNullException("Null in parameter " & i)
        If Not Marshal.IsComObject(comObjects(i)) Then Throw New ArgumentException(comObjects(i).GetType.Name & " is not a COM object")
    Next

    Return New ComContext(comObjects)
End Function

Private Class ComContext : Implements IDisposable
    Private m_ComObjects As Object()
    Private m_Disposed As Boolean

    Sub New(ByVal comObjects As Object())
        m_ComObjects = comObjects
    End Sub

    Private Sub Dispose() Implements IDisposable.Dispose
        For Each item In m_ComObjects
            Marshal.FinalReleaseComObject(item)
        Next

        GC.SuppressFinalize(Me)
    End Sub

End Class

1 Ответ

1 голос
/ 27 февраля 2010

Мне нравится идея, куда ты идешь. Я более склонен оборачивать COM-объект, который я использую, в тип IDisposable, где этот тип предоставляет открытые члены COM-объекта (думаю: Adapter). Затем метод Dispose () в вашем классе будет обрабатывать сборку мусора COM-объекта.

Если вы используете много COM-объектов, вы можете наследовать от базового класса для обработки удаления. Я вообще не тестировал этот код, но обычно это то, о чем я думаю ...

public abstract class COMAdapter : IDisposable {

    protected abstract object COMObject { get; }

    public void Dispose() {
        Marshal.FinalReleaseComObject(COMObject);
        GC.SuppressFinalize(this);
    }
}

public class ConcreteAdapter : COMAdapter {
    private YourCOMType _comObject;

    protected override object COMObject {
         get { return _comObject; }
    }
}
...