#c_sharp
У меня есть несколько классов которые создают в конструкторе Thread (запуск производится отдельном методе - Start). Необходимо что бы классы не уничтожались до завершения работы потоков (они не фоновые, достаточно быстро отрабатывают, и желательно дождаться их завершения, а не сразу убивать при завершении приложения). В связи с этим вопрос, где выполнять ожидание завершения потока (.Join) - в финализаторе (или деструкторе) или Dispose ?
Ответы
Ответ 1
Логика неправильная - Dispose по майкрософтовским гаедлайнам должен выполняться за минимально возможное время. То есть выполнять какое-то ожидание завершения операции нужно в юзерском коде, а не в Dispose и, разумеется, не в финалайзере. Отдельный аргумент против ожидания завершения потока в Dispose - сборщик мусора вполне себе имеет право (и даже разумно делать его таким) быть однопоточным. Соответственно, если вы лепите Wait в Dispose, то на время ожидания завершения потока у вас саспендится сборка мусора, а это очень плохо. Проанализируйте ваш текущий код - наверняка есть способ инвертировать логику вашего приложения, чтобы работающие потоки не доходили до Dispose. Активнее оперируйте TaskPlanner'ами и сервисами ThreadFactory, введите Producer-Consumer. Хороших решений - масса.Ответ 2
Финализатор (деструктор) C# предназначен для освобождения неуправляемых ресурсов на случай, если пользователь не вызвал Dispose() и не освободил ресурсы там. Финализатор вызывается сборщиком мусора. Когда CLR запускает сбор мусора, все остальные потоки приостанавливаются. Поэтому, теоретически, вы получите deadlock, если будете ожидать другой поток в финализаторе. Вообще, финализатор не должен делать ничего больше, кроме освобождения неуправляемых ресурсов (указателей, handle'ов операционной системы). С этой точки зрения ожидать завершение потока лучше в Dispose(), т.к. вы сами вызываете этот метод.
Комментариев нет:
Отправить комментарий