Почему NativeWindow не может быть финализирован
Вольный перевод поста NogginBops "Why NativeWindow can't be finalized"
Пост не является авторским и/или официальным.
Более того - он так же не является профессиональным.
Автор оригинала: NogginBops
Ссылка на оригинал: Why NativeWindow can't be finalized
Пост может вводить в заблуждение, поскольку может создаться впечатление, что финализация окна это то, что вы будете делать. Но, по факту, это Плохая Идея™. Врядли вам нужны окна, которые будут существовать какое-то неопределенное время, пока сборщик мусора не решит их финализировать - это был бы очень странный пользовательский опыт. Вместо этого мы можем рассматривать исключение в финализаторе
NativeWindowкак своего рода механизм обнаружения утечек памяти, указывающий на то, что вы забыли должным образом освободить ресурсы. Таким образом, следует рассматривать ситуацию с другой точки зрения: почемуNativeWindowвыбрасывает исключение, если вы не освобождаете ресурсы должным образом до его финализации?
В предыдущей статье мы рассмотрели GLFWProvider.CheckForMainThread. Там мы пришли к выводу, что большинство функций GLFW необходимо вызывать из основного потока. В этой статье мы рассмотрим еще одно следствие этого: NativeWindow не может быть финализирован.
Если вы попытаетесь сделать это, позволив сборщику мусора удалить NativeWindow, вы столкнетесь с исключением GLFWException, содержащим следующее сообщение:
You can only dispose windows on the main thread. The window needs to be disposed as it cannot safely be disposed in the finalizer.
Окно может быть освобождено только в основном потоке. Окно должно быть освобождено, поскольку его нельзя безопасно освободить в финализаторе.
Так почему же это так? Ну, простой ответ лежит в предыдущем посте: Большинство функций GLFW необходимо вызывать из основного потока. А финализаторы в C# запускаются не из основного потока, они запускаются в своем специальном потоке финализации. Это означает, что мы не можем вызывать функции GLFW в финализаторе, а следовательно — не можем уничтожить окно GLFW. Вместо этого мы выбрасываем исключение, чтобы, как мы надеемся, уведомить программиста о его ошибке.
Но теперь вы можете спросить: Я не освобождаю NativeWindow, и у меня не происходит никаких сбоев, в чем же дело?
Что ж, dotnet не гарантирует, что сборщик мусора действительно выполнит финализатор объекта до завершения программы. Из документации по финализаторам:
… you can’t guarantee the garbage collector calls all finalizers before exit, you must use Dispose or DisposeAsync to ensure resources are freed.
… вы не можете гарантировать, что сборщик мусора вызовет все финализаторы до завершения, вы должны использовать Dispose или DisposeAsync, чтобы гарантировать освобождение ресурсов.
Поэтому убедитесь, что вы освобождаете ресурсы вашего NativeWindow либо с помощью using, либо вручную вызывая .Dispose().
Примечание от переводчика:
Подробнее шаблон IDisposable описан в .NET Platform Architecture book
Пост не является авторским и/или официальным.
Более того - он так же не является профессиональным.
Автор оригинала: NogginBops
Ссылка на оригинал: Why NativeWindow can't be finalized
