Лучший способ предотвратить ранний сбор мусора в CLR - PullRequest
2 голосов
/ 28 апреля 2010

Я написал управляемый класс, который оборачивается вокруг неуправляемого объекта C ++, но я обнаружил, что - при использовании его в C # - GC запускается рано, пока я выполняю метод для объекта. Я прочитал о сборке мусора и о том, как предотвратить это на ранней стадии. Одним из способов является использование оператора «using» для контроля за удалением объекта, но это накладывает ответственность на клиента управляемого объекта. Я мог бы добавить к управляемому классу:

MyManagedObject::MyMethod() {</p> <pre><code>System::Runtime::InteropServices::GCHandle handle = System::Runtime::InteropServices::GCHandle::Alloc(this); // access unmanaged member handle.Free();

}

Это похоже на работу. Будучи новичком в .NET, как другие люди решают эту проблему?

Спасибо,

Юхан

Ответы [ 2 ]

3 голосов
/ 05 ноября 2012

Возможно, вы захотите взглянуть на эту статью: http://www.codeproject.com/Tips/246372/Premature-NET-garbage-collection-or-Dude-wheres-my. Я считаю, что она точно описывает вашу ситуацию. Короче говоря, лекарства - это либо блок using, либо GC.KeepAlive. Однако я согласен с тем, что во многих случаях вы не захотите передавать это бремя клиенту неуправляемого объекта; в этом случае хороший вызов - вызов GC.KeepAlive (this) в конце каждого метода-оболочки.

2 голосов
/ 28 февраля 2011

Вы можете использовать GC.KeepAlive(this) в теле вашего метода, если хотите избежать вызова финализатора. Как правильно отметили другие в комментариях, если ваша ссылка this не активна во время вызова метода, возможно, что финализатор вызван и память восстановлена ​​во время вызова.

См. http://blogs.microsoft.co.il/blogs/sasha/archive/2008/07/28/finalizer-vs-application-a-race-condition-from-hell.aspx для подробного изучения случая.

...