2011-12-19 9 views

Odpowiedz

7

Punktem obu tych struktur jest zapobieganie zwolnieniu zasobu przez moduł gromadzący śmieci i unieważnienie uchwytu przed zakończeniem wywołania P/Invoke. Powiązana dokumentacja wskazuje, że są to specjalne typy rozpoznawane przez koordynatora międzyoperacyjnego.

Z dokumentacji wynika, że ​​HandleRef jest w zasadzie szczególnym przypadkiem bardziej ogólnej struktury GCHandle.

Struktura HandleRef jest specjalnie przeznaczona do zawijania uchwytów do zasobów niezarządzanych, które są używane z kodem P/Invoke. Na przykład klamki okien (HWND) lub konteksty urządzeń (HDC). Ma właściwość Handle, która zwraca wartość typu IntPtr, która jest wartością całkowitą wielkości wskaźnika na architekturze bazowego systemu. Możesz użyć tego, aby szybko uzyskać łatwy w obsłudze uchwyt, który się zawija.

Podczas gdy struktura GCHandle pozwala określić rodzaj rękojeści owija stosując jeden z członków GCHandleType wyliczenie, struktura HandleRef został specjalnie zaprojektowany, aby owinąć uchwyty do niezagospodarowanych zasobów. Prawdopodobnie używałbyś struktury GCHandle, gdy masz do czynienia bezpośrednio z pamięcią niezarządzaną, a nie ze specjalnymi uchwytami, które Win32 API traktuje jako czarne pola.

Nie trzeba używać żadnego z nich. Można po prostu zadzwonić pod numer GC.KeepAlive, aby garbage collector nie zwolnił przedwcześnie zasobu.

Nawet to prawdopodobnie nie jest konieczne. Piszę kod P/Invoke od lat i odkryłem, że jeśli jest poprawnie napisany, nie ma potrzeby, aby jedna z tych struktur była. Jeśli obiekt klasy pobiera śmieci zebrane podczas wykonywania połączenia API w trakcie wykonywania, oznacza to błąd w aplikacji. W rzeczywistości chcę, aby otrzymał powiadomienie o błędzie przez wyjątek, a nie ukrywać go.

+0

Dzięki za odpowiedź –

+1

"Odkryłem, że jeśli jest poprawnie napisana, nie ma potrzeby, aby jedna z tych struktur." Co, jeśli nie martwisz się, że obiekt nie zostanie zebrany, ponieważ wiesz, że zarządzany kod będzie go odnosił, ale po prostu chcesz, aby niezarządzany kod akceptował/wstrzymywał/zwracał zarządzane referencje z jakiegoś powodu. Przykład użycia: stackoverflow .pl/pytania/32105089 –

0

Jedną z różnic jest podana w link wspomniałeś:

Typ wartości HandleRef, jak GCHandle, jest szczególnym rodzajem uznane przez interoper Marshaler. Normalny, nie podpartego GCHandle również zapobiega przedwczesnego zbierania śmieci, ale HandleRef zapewnia lepszą wydajność . Chociaż używanie HandleRef do utrzymywania obiektu przy życiu przez czas trwania wywołania platformy jest preferowane, można również użyć metody GC.KeepAlive w tym samym celu.

+0

Tak, widzę to, ale potrzebuję szczegółowych informacji. –

+1

@user: Jakich jeszcze informacji szczegółowych potrzebujesz? –

Powiązane problemy