Недавно мне нужно было сравнить предложенный шаблон для IDisposable и завершения объекта с помощью автогенератора, который предоставляет VS2005/VB.NET. Мы использовали автоматически сгенерированный один из них, но после просмотра двух бок о бок у меня возник ряд вопросов о реализации VB.NET ...Почему VS2005/VB.NET реализует интерфейс IDisposable с перегрузкой Dispose (удаление в виде логического)?
Для справки: реализация IDE:
Public Class Class1
Implements IDisposable
Private disposedValue As Boolean = False ''// To detect redundant calls
''// IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
''// TODO: free managed resources when explicitly called
End If
''// TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
''// This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
''// Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Вопросы:
- Если Finalize() вызывается во время GC без object.Dispose(), которые явно называют первым затем утилизации: = ложь и код внутри "если утилизации ..." никогда не будет выполнить, чтобы освободить управляемые ресурсы, в результате чего они останутся в памяти до следующего прохождения GC. Почему бы им не было явно освобождено? Не сделал бы так свободной памяти на первом проходе GC и не оставил ненужные объекты в памяти до следующего прохода?
- Почему среда IDE не генерирует вызов Dispose (false) при переопределении Finalize() в классе IDisposable?
- Как бы GC знал, чтобы вызвать Dispose (false), и убедиться, что это реализация IDE, а не пользовательская реализация, которая использует параметр bool другим способом? * ... и не должен Dispose (распоряжаться как bool) быть членом интерфейса, если GC проверяет его существование и использует его таким образом, который предполагает определенную реализацию (object.Dispose (disposing: = false))? * При наличии как
Dispose()
, так иDispose(disposing as boolean)
почему GC когда-либо выбирает вызов перегруженного, неинтерфейсного элемента?
В целом я смущен предполагаемой добавленной стоимости, имеющих расширенный код-путь, который выполняется, когда Dispose()
называется явным образом (в отличие от того, общий путь, который выполняется независимо от того, или нет Dispose()
была вызвана явно) , Хотя я могу оценить, что он обеспечен хорошими намерениями, я не вижу, как он делает что-то другое, кроме как задерживает фактический выпуск управляемых ресурсов, если Dispose()
не вызывается напрямую. По сути, кажется, только работает, чтобы сделать управляемые ресурсы недоступными в графе объектов, осиротевших их до тех пор, пока второй GC не будет освобождать их в точке, где, как известно, больше не требуется.
Спасибо, что заметили это; Я перепутал поля (теперь я исправил это). Вы также частично отвечаете на мой вопрос, заявляя, что GC не будет вызывать Dispose (false), что заставляет меня задаться вопросом, почему VS2005 использует эту перегрузку вообще. Есть ли когда-нибудь случай, когда Dispose (false) будет выполняться? Разбивается ли это VS, так что * if * I переопределяет Finalize(), тогда я могу вызвать Dispose (false)? Кажется забавным, так как IDE не заглушает какой-либо код, если я переопределяю Finalize() – STW
Я отредактировал свой ответ; GC вызывается Dispose (false), как вы описываете. Причиной этого является то, что управляемые компоненты, которые будут расположены с помощью Dispise (true), будут (или, скорее, ДОЛЖНЫ быть) индивидуально завершены и удалены GC. –
Интересные вещи. Я заметил, что в C# реализация интерфейса IDisposable не создает перегрузку; однако запуск анализа кода без перегрузки (либо на C#, либо на VB.NET) генерирует два предупреждения, инструктирующие вас добавить перегрузку. – STW