catching "System.InvalidOperationException: ..."
От: Аноним  
Дата: 12.12.06 16:52
Оценка:
Доброго дня суток.

Очень нужен совет. Я участвую в большом проекте, и переодически возникают эксепшены типа:
Exception:
System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

Из-за чего это происходит понятно, а вот как отловить то место где был не закрыт ридер? Долгий поиск по исходникам ничего не дал (уж очень много кода), всавлять где только можно дебаг инфу нельзя (по понятным причинам).

Подскажите механизм как отловить место проблемы?

Заранее благодарен.
Re: catching "System.InvalidOperationException: ..."
От: Saruwatari Россия  
Дата: 12.12.06 18:57
Оценка:
Здравствуйте, Аноним.

Отловить ситуацию, когда у Вас происходит обращение к уже открытому ридеру можно только с помощью ведения лога обращений к базе, в котором будут фиксировать открытия, закрытия и прочие операции с БД. Как Вы это сделаете — Ваше дело.
Кроме того, в первую очередь я посмотрел бы все ли блоки, в которых есть работа с ридерами, имеют закрытие этого ридера. Возможно где-то вываливается по эксепшену и закрытие не происходит. Посмотрите, чтобы везде были блоки try{...}finally {... daraReader.Close(); } и т.д.
Re[2]: catching "System.InvalidOperationException: ..."
От: Аноним  
Дата: 12.12.06 20:36
Оценка:
Здравствуйте, Saruwatari, Вы писали:

S>Здравствуйте, Аноним.


S>Отловить ситуацию, когда у Вас происходит обращение к уже открытому ридеру можно только с помощью ведения лога обращений к базе, в котором будут фиксировать открытия, закрытия и прочие операции с БД. Как Вы это сделаете — Ваше дело.

S>Кроме того, в первую очередь я посмотрел бы все ли блоки, в которых есть работа с ридерами, имеют закрытие этого ридера. Возможно где-то вываливается по эксепшену и закрытие не происходит. Посмотрите, чтобы везде были блоки try{...}finally {... daraReader.Close(); } и т.д.

спасибо за совет, но я вроде просмотрел весь код и вроде везде используется патерн
using (SqlDataReader reader = someCommend.ExecuteReader())
{
...
}


вот в одном из таких мест вылетает эта ошибка. Словить ее я могу, вот только как на момент получения ошибки определить где он раньше использовался. В дебаг режиме получить никак, ошибка проявляется при большой нагрузке системы, соответсвенно и логи к базе будут просто огромными.

Может кто знает как в С# на момент получения ошибки сделать дамп всех коннекшенов (к примеру в EventViewer) с информацией кто (сборка, клас, ...) и когда его создал?
Re[3]: catching "System.InvalidOperationException: ..."
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 12.12.06 21:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>спасибо за совет, но я вроде просмотрел весь код и вроде везде используется патерн

А>
А>using (SqlDataReader reader = someCommend.ExecuteReader())
А>{
А>...
А>}
А>


Вероятно, внутри одного из using'ов происходит вызов функции, в которой второй using с той же SqlCommand.
В этом случае можно остановиться в месте, где выбрасывается исключение и искать выше по стеку.

Также может оказаться, что ридер открыт в другом потоке... В этом случае также останавливайся по выбросу
исключения и листай стек каждого потока.

Думаю, должно получиться, тем более, что известно, какой именно экземпляр SqlCommand повторно используется.
Re[4]: catching "System.InvalidOperationException: ..."
От: Аноним  
Дата: 12.12.06 21:59
Оценка:
Здравствуйте, Михаил Можаев, Вы писали:

ММ>Вероятно, внутри одного из using'ов происходит вызов функции, в которой второй using с той же SqlCommand.

ММ>В этом случае можно остановиться в месте, где выбрасывается исключение и искать выше по стеку.
точно, это я уже проделывал путем дампа стека, такой метод ничего не выявил .

ММ>Также может оказаться, что ридер открыт в другом потоке... В этом случае также останавливайся по выбросу

ММ>исключения и листай стек каждого потока.
а можно поподробнее как это? и если возможно как это сделать программно, что бы записать в EventViewer.

ММ>Думаю, должно получиться, тем более, что известно, какой именно экземпляр SqlCommand повторно используется.
Re[5]: catching "System.InvalidOperationException: ..."
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 12.12.06 22:36
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>точно, это я уже проделывал путем дампа стека, такой метод ничего не выявил .


Зачем дамп, если можно отладчиком остановиться в месте выброса исключения и спокойно все посмотреть?

ММ>>Также может оказаться, что ридер открыт в другом потоке... В этом случае также останавливайся по выбросу

ММ>>исключения и листай стек каждого потока.
А>а можно поподробнее как это? и если возможно как это сделать программно, что бы записать в EventViewer.

В любом случае надо сделать так, чтобы при выбросе исключения мы попадали в отладчик (Debug->Exceptions...).
Затем ловим исключение, открываем список потоков и переключаясь между ними рассматриваем стек.
Ничего лучшего предложить не могу.

В EventViewer писать нет смысла, т.к. для этого надо встраивать отладочную печать во многие места.
Просто делать дамп не получится.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.