Podejrzewam, że powodem, dla którego ta funkcja nie istnieje, jest to, że jej realizacja jest złożona i niewielu ludzi jej potrzebuje. Aby być bezpiecznym, chcesz, aby przypinanie działało przechodnie, tzn. Chcesz przypiąć cały wykres dostępnych obiektów. Ale nie wydaje się, że czegoś zasadniczo nie da się zrobić.Dlaczego GCHandle.Alloc nie może przypinać obiektów zawierających odniesienia?
przykład, załóżmy, że masz następujące klasy:
[StructLayout(LayoutKind.Sequential)]
class SomeObject
{
public SomeObject r;
}
które można przydzielić jak:
SomeObject o = new SomeObject();
i próby przypiąć go:
GCHandle oh = GCHandle.Alloc(o, GCHandleType.Pinned);
będziesz złapać strach:
Object contains non-primitive or non-blittable data.
OK, dobrze, mogę z tym żyć. Ale przypuśćmy, że mam dostęp do implementacji garbage collectora .NET. Jakie byłyby przeszkody? Oto przeszkody, które widzę:
- Kołowe odniesienia.
- Chcesz, by garbage collecting ograniczył się do obiektów wewnątrz sterty aplikacji.
- Może to zająć dużo czasu.
- Ciężko/bolesnie uczynić operację atomową.
Wydaje mi się, że GC ma już do czynienia z niektórymi z tych problemów. Co więc zapominam?
UWAGA: Zanim zapytasz "Co chcesz osiągnąć?", Itp., Celem moich pytań jest kod badań, niekoniecznie ograniczony do C# i niekoniecznie ograniczony do CLR. Rozumiem, że manipulowanie pamięcią w środowisku wykonawczym nie jest typowym scenariuszem. W każdym razie nie jest to kwestia czysto spekulatywna.
UWAGA 2: Poza tym nie dbam o marshaling. Po prostu martwię się o przypinanie.
Co by to znaczyło, gdyby zmodyfikować odniesienie wewnątrz przypiętego obiektu? Czy odpiąłby stare referencje i przypiął nowy? Obliczenie przechodniego zamknięcia referencji jest tak kosztowne, jak GC. Teraz chcesz to zrobić w dowolnym momencie zmiany odniesienia w dowolnym miejscu w systemie? –
Ta odpowiedź nie ma sensu. Na początek nic o GC nie jest przypadkowe. Poza kontrolą, tak. Ale to nie ma znaczenia: jeśli przypinam obiekt, mam stabilny wskaźnik do tego obiektu. Teraz znajduję pola tego przypiętego obiektu (również stabilnego), otrzymuję odnośnik do wskazanego obiektu i przypinam go. Nic w tym procesie nie sprawia, że referencje są mniej stabilne, a więc przez indukcję powinienem być w stanie przechylić cały wykres obiektów przechodniowo. Nie chcesz przypinać więcej niż raz, ale to jest szczegół implementacji. CHCĘ przypiąć cały wykres obiektów, dlatego pytam. –
Heja, nie oczekiwałem, że będziesz zadowolony z odpowiedzi. Mówisz, że dobrze to zrobisz, projektanci CLR zwątpili w to, powiedzieli "nie" i to już koniec. Możesz publikować prośby o nowe funkcje w witrynie connect.microsoft.com lub udostępniać ją w Mono. –