Looking for c# Keywords? Try Ask4Keywords

C# Language Связанный объект


пример

GC (Garbage Collector) несет ответственность за очистку нашего мусора.

В то время как GC очищает наш мусор, он удаляет неиспользуемые объекты из управляемой кучи, которые вызывают фрагментацию кучи. Когда GC выполняется с удалением, он выполняет сжатие кучи (defragmintation), которое включает в себя перемещение объектов в куче.

Поскольку GC не является детерминированным, когда передается ссылка на управляемый объект / указатель на собственный код, GC может ударить в любое время, если это происходит сразу после вызова Inerop, есть очень хорошая вероятность того, что объект (эта ссылка передана на native) будет перемещаться по управляемой куче - в результате мы получаем неверную ссылку на управляемую сторону.

В этом случае вы должны привязать объект до передачи его в собственный код.

Связанный объект

Прикрепленный объект - объект, который не разрешен для перемещения по GC.

Gc Pinned Handle

Вы можете создать контактный объект, используя метод Gc.Alloc

GCHandle handle = GCHandle.Alloc(yourObject, GCHandleType.Pinned); 
  • Получение привязанного GCHandle к управляемому объекту маркирует определенный объект как тот, который не может быть перемещен GC , пока не освободит дескриптор

Пример:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern void EnterCriticalSection(IntPtr ptr);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern void LeaveCriticalSection(IntPtr ptr);
       
public void EnterCriticalSection(CRITICAL_SECTION section)
{
    try
    {
        GCHandle handle = GCHandle.Alloc(section, GCHandleType.Pinned); 
        EnterCriticalSection(handle.AddrOfPinnedObject());
        //Do Some Critical Work
        LeaveCriticalSection(handle.AddrOfPinnedObject());
    }
    finaly
    {
        handle.Free()
    }
}

Меры предосторожности

  • При фиксации (особенно больших) объектов старайтесь как можно быстрее освободить закрепленный GcHandle, так как он прерывает дефрагментацию кучи.
  • Если вы забудете освободить GcHandle, ничего не будет. Сделайте это в разделе безопасного кода (например, finaly)