NHibernate Session ObjectDisposedException
Есть ли способ проверить, была ли сессия уничтожена NHibernate?
У меня есть класс-оболочка в Session, который имеет свою собственную реализацию Finalizer и IDispoable, однако, если Session удаляется до того, как я сам обработаю его в своем классе, я получаю исключение ObjectDisposedException.
Я действительно не хочу обернуть мой код очистки
try {
...
}
catch (ObjectDisposedException) { }
Но я не совсем уверен в другом. Свойства Session.IsOpen и Session.IsActive, по-видимому, не предоставляют мне никакой достоверной информации, подтверждающей, что сеанс был удален.
Для полного источника вы можете просмотреть его на Assembla.
3 ответа
Хорошо, просто взглянул на ваш код. Я не знаю, является ли это именно проблемой, но вы вызываете End() из метода dispose диалога, который, в свою очередь, пытается восстановить соединение и удаляет сеанс... если вы явно вызвали End() до этого, вы получите что вы получаете, избегайте этого звонка. Я думаю, вам не следует беспокоиться об откате транзакции до завершения сеанса, поскольку это делается неявно. Просто бросил быстрый взгляд, но я думаю, что мне действительно нравится ваша реализация.
"Это одна из самых абсурдных вещей, которые я когда-либо видел, чтобы это свойство Open оставалось верным даже после утилизации"
Почему уже размещенный вами объект содержит достоверную информацию о его состоянии? Вы не должны пытаться использовать удаленный сеанс, я не знаю, где nhibernate утилизирует ваш сеанс, вы уверены, что не утилизируете его самостоятельно?.
Я всегда думал, что лучшая практика с NHibernate - это "сессия на запрос", что означает, что он должен жить только внутри области "использования".
using(Session session = new Session())
{
}
Я бы посоветовал попытаться запретить двум людям использовать сеанс / разговор. Если вы управляете созданием сессий, вы можете обернуть его в свой собственный impession ISession, который выполняет собственную проверку IsAlreadyDisposed(), чтобы предотвратить исключение. Тем не менее, учитывая это усилие против "ожидаемого исключения" и оригинальный код выглядит не так уж плохо.
Я бы также предложил следить за реализацией вашего финализатора. "Session.Is().InTransaction()" переходит в Session->Transaction, и к тому времени, когда финализатор возвращается к нему, сессия может быть нулевой. Навигация по управляемым отношениям во время финализатора не гарантируется.