Мы все знаем шаблон System.IDisposable. Это было описано время Zillion, также здесь, на StackOverflow:Почему Dispose() не должен распоряжаться управляемыми ресурсами и финализатором?
ссылка: Dispose() for cleaning up managed resources?
Одноразовых узоров советует, что я должен только распоряжаться управляемыми ресурсами, если мой объект расположен, а не во время завершения
Вы можете видеть, что это происходит потому, что следующий код рекомендуется:
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
}
I что мой класс должен внедрять System.IDisposable всякий раз, когда у моего класса есть (частный) член, который реализует System.IDisposable. Dispose (bool) должен вызвать Dispose() частного члена, если логическое распоряжение является истинным.
Почему это проблема, если Dispose будет вызываться во время финализации? Итак, почему следующий Dispose будет проблемой, если он вызывается во время финализации?
protected void Dispose(bool disposing)
{
if (myDisposableObject != null)
{
myDisposableObject.Dispose();
myDisposableObject = null;
}
}
Финализаторы [не гарантируются выполнение в детерминированном порядке] (http://stackoverflow.com/questions/4163603/why-garbage-collector-takes-objects-in-the-wrong-order). В частности, любая из ваших управляемых ссылок, возможно, уже была доработана до того, как будет вызываться ваш финализатор. –
@DanBryant Не только финализировано либо - ссылки, которые ваш экземпляр имеет на другие объекты, больше не являются обязательными для GC, поэтому управляемые объекты, на которые вы ссылаетесь, могли быть уже собраны *. Даже проверку 'myDisposableObject! = Null' недостаточно, так как вы находитесь в многопоточной среде - эта ссылка может быть отменена между проверкой и вызовом' Dispose'. И, наконец, вполне вероятно, что финализатор на этом объекте также был запланирован (и, возможно, даже закончен) уже, так что его утилизация, вероятно, выполняется как на управляемой, так и на неуправляемой стороне. – Luaan
По правде говоря, вам вообще не нужно будет реализовывать финализатор. Все необходимые вам финализаторы уже написаны - используйте безопасные ручки, и вы должны быть в порядке почти все время. Они могут быть полезны для целей отладки («забыл избавиться от этого объекта»), но вам редко нужны они для того, для чего они предназначены - освобождение неуправляемых ресурсов управляемого объекта. В вашем случае вопрос, который вы задаете, уже предает это - вам нужно только заботиться о неуправляемых ресурсах; вызов 'Dispose' на другом управляемом объекте является вмешательством, где вы не должны. Не делай этого. – Luaan