Как использовать Finalize с управляемыми ресурсами?

Я не на 100 % понимаю, как экземпляр класса A может существовать до тех пор, пока не будет завершен последний экземпляр класса B.

Или, другими словами, я бы хотел, чтобы все B вызывали методы close&dispose в A внутри финализации B... и чтобы это произошло до завершения A.

Сценарий:

О. У меня есть управляемая оболочка для неуправляемого ресурса. Для аналогии назовем A файловой системой.

B. управляемые ресурсы, которые ссылаются на A, которые, в свою очередь, запросили неуправляемый ресурс через оболочку A. Для аналогии давайте назовем B файлом.

Дополнительный запрос --> Я бы хотел, чтобы синтаксис using работал хорошо. т. е. явный вызов использования dispose не должен удалять неуправляемый ресурс. Объект будет жить в пуле объектов. Его следует удалять только тогда, когда он покидает пул объектов.

class SomeClass() : IDisposable{

    public SomeClass(){}

    public ~SomeClass(){
       // dispose of unmanaged here?
    }

    // Dispose(bool disposing) executes in two distinct scenarios.
    // If disposing equals true, the method has been called directly
    // or indirectly by a user's code. Managed and unmanaged resources
    // can be disposed.
    // If disposing equals false, the method has been called by the
    // runtime from inside the finalizer and you should not reference
    // other objects. Only unmanaged resources can be disposed.
    public void Dispose(bool disposing) {
        if (disposing) {
            // dispose managed
        } else {
            // dispose unmanaged?
        }
    }

    public void Dispose() {
        Dispose(true);
        //GC.SuppressFinalize(this);
    }

}

Использованная литература:

[1] Почему метод Finalize не может быть переопределен

[2] CLR через C Sharp, 3-е изд. Ч. 21. Объект критического финализатора. В частности, стр. 537 «Использование финализации с управляемыми ресурсами».


person sgtz    schedule 15.04.2012    source источник
comment
Вы пытаетесь выполнить работу сборщика мусора. Пока есть живые ссылки на объекты B, сбор A невозможен. Как только все B собраны, A тоже собирается. Теперь уже не имеет значения, в каком порядке они дорабатываются.   -  person Hans Passant    schedule 15.04.2012
comment
@HansPassant: включает ли это сценарии IsFinalizingForUnload + HasShutdownStarted?   -  person sgtz    schedule 15.04.2012
comment
Ничего особенного в этих условиях, просто финализатор, когда ваша программа закрывается. Мне совершенно непонятно, почему вы беспокоитесь обо всем этом.   -  person Hans Passant    schedule 15.04.2012
comment
@HansPassant: все началось после обнаружения кода, в котором Dispose (через использование) закрывал то, чего не должно было быть. Это привело к попытке лучше справиться с dispose + unmanaged в целом... и... в результате были обнаружены некоторые пограничные случаи + соглашения .net framework.   -  person sgtz    schedule 16.04.2012
comment
@HansPassant: обучение доступно + воскрешение дает уверенность. кстати: в этой ситуации лучше всего не реализовывать finally на дочерних объектах (как это делает фреймворк). кстати: AddMemoryPressure, RemoveMemoryPressure и ReRegisterForFinalize выглядят весьма полезными для некоторых, будь то редкие ситуации. Иначе бы я о них не узнал.   -  person sgtz    schedule 16.04.2012


Ответы (1)


Вы не можете контролировать порядок финализации в целом. Однако вы можете управлять двухэтапным порядком, используя CriticalFinalizerObject. . Также посмотрите на инфраструктуру SafeHandle и то, как FileStream это делает.

Если этого недостаточно, вы можете произвольно контролировать время жизни, создавая ссылки на объекты из статического члена класса (например, списка или словаря). Только когда вы отпустите эти ссылки, финализация может произойти. Таким образом, вы создадите ссылку на A, которую вы очистите, как только заметите, что GCHandle для B стал недействительным.

person usr    schedule 15.04.2012
comment
в [2] г-н Рихтер на стр. 537 говорит: «Хотя финализация используется почти исключительно для выпуска собственного ресурса, иногда она может быть полезна и для управляемых ресурсов. Мне кажется, есть способ. Я еще не изучил эту главу на 100%... поэтому я обращаюсь к экспертам. - person sgtz; 15.04.2012
comment
Я думаю, он имеет в виду возможность использовать финализацию для пулов объектов. Однако вы не можете контролировать порядок, за исключением того, что я упомянул. - person usr; 15.04.2012