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.
Dzięki za odpowiedź –
"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 –