2010-04-02 10 views
6

Do niedawna uważałem, że środowisko wykonawcze .NET tylko zwiększa liczbę odwołań obiektów COM o 1 podczas tworzenia runtime-callable wrapper i że dla danego obiektu COM tworzony jest tylko jeden taki wrapper do wywoływania w środowisku wykonawczym.Kiedy środowisko wykonawcze .NET wstrzymuje liczbę odwołań> 1 dla obiektów COM?

Jeśli się nie mylę, powyższe oznacza, że ​​Marshal.FinalReleaseComObject i Marshal.ReleaseComObject robią to samo w praktyce.

Jednak dzisiaj pisałem kilka testów, aby zweryfikować, czy obiekty COM są poprawnie zwolnione przez mój kod. Robię to poprzez wywoływanie rzekomo zwolnionego obiektu i sprawdzanie oczekiwanego InvalidComObjectException. Okazuje się, że są przypadki, w których wyjątek jest zgłaszany po FinalReleaseComObject, ale nie po ReleaseComObject.

Czy to oznacza, że ​​środowisko wykonawcze .NET 2.0 może zawierać więcej niż jedno odwołanie do obiektu COM? Jeśli tak, kiedy to robi?

Odpowiedz

5

Istnieje tu dodatkowy poziom niezależności. Tak, RCW przechowuje pojedynczą liczbę referencyjną na natywnych wskaźnikach interfejsu COM. Ale RCW ma również licznik referencyjny, jest zwiększany za każdym razem, gdy wskaźnik interfejsu COM jest mapowany na RCW. Co może się zdarzyć, jeśli metoda COM zwróci wskaźnik interfejsu. Finalizator odpowiedniej klasy opakowującej .NET zmniejsza ją.

Możesz majstrować przy tej liczbie referencyjnej bezpośrednio przez Marshal.ReleaseComObject(), która zmniejsza ją o jeden, tak jak finalizator, i Marshal.FinalReleaseComObject(), który przerywa ją do zera, gwarantując, że IUnknown :: Release () Metoda jest wywoływana. Oni oczywiście należą do kategorii "lepiej wiedzieć, co robisz". Nieprawidłowe wykonanie powoduje powstanie brzydkiego i niewiarygodnego wyjątku "Obiekt COM oddzielony od podstawowego RCW".

Powiązane problemy