Страница: 1 |
Страница: 1 |
Вопрос: как правильно работать с try catch и dispose
Добавлено: 17.01.07 07:49
Автор вопроса: Neco | Web-сайт:
глупый вопрос, но просто сейчас я ромажу вот такие конструкции:
Dim ora_conn As OracleClient.OracleConnection = Nothing
Dim ora_comm As OracleClient.OracleCommand = Nothing
Try
'Throw New Exception("1")
ora_conn = New OracleClient.OracleConnection("Data Source=" + "bittl" + _
";Persist Security Info=True;User ID=" + "reporter" + _
"; Password=" + "xxxxxxxxx" + ";Unicode=False")
'Throw New Exception("2")
ora_comm = New OracleClient.OracleCommand()
ora_comm.Connection = ora_conn
'Throw New Exception("3")
ora_conn.Open()
'Throw New Exception("4")
Catch ex As Exception
Throw ex
Finally
Try
ora_conn.Close()
ora_conn.Dispose()
Catch ex As Exception
End Try
Try
ora_comm.Dispose()
Catch ex As Exception
End Try
End Try
End Sub
и мало того, что мне не нравится заключать каждую созданную команду в Finally в Try Catch - я ведь ещё и не закрываю коннект, если происходит исключение после его открытия.
Т.е. получается, что по-хорошему надо накручивать это:
Dim ora_conn As OracleClient.OracleConnection = Nothing
Dim ora_comm As OracleClient.OracleCommand = Nothing
Try
Throw New Exception("1")
ora_conn = New OracleClient.OracleConnection("Data Source=" + "bittl" + _
";Persist Security Info=True;User ID=" + "reporter" + _
"; Password=" + "xxxxxxx" + ";Unicode=False")
'Throw New Exception("2")
ora_comm = New OracleClient.OracleCommand()
ora_comm.Connection = ora_conn
'Throw New Exception("3")
ora_conn.Open()
'Throw New Exception("4")
Catch ex As Exception
Try
If ora_conn IsNot Nothing Then
ora_conn.Close()
ora_conn.Dispose()
End If
If ora_comm IsNot Nothing Then
ora_comm.Dispose()
End If
Catch ex1 As Exception
Throw ex1
End Try
Throw ex
Finally
Try
If ora_conn IsNot Nothing Then
ora_conn.Close()
ora_conn.Dispose()
End If
If ora_comm IsNot Nothing Then
ora_comm.Dispose()
End If
Catch ex As Exception
Throw ex
End Try
End Try
но одинаковый участок кода мне вообще не нравится, да ещё и такая куча получилась, а полезной нагрузки - ноль! Да и этот код не выполняет всего, что хотелось бы - исключение ex1 вызовется, если при разрушении объекта произойдёт исключение и тем самым перекроет исключение ex - и внешняя процедура не узнает о реальных причинах сбоя.
Так вопрос: как ПРАВИЛЬНО совмещать блоки Try Catch, исключения и корректное высвобождение ресурсов?
Ответы
Всего ответов: 10
Номер ответа: 1
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #1
Добавлено: 17.01.07 08:19
ora_conn.Dispose()
А почему ты решил что эти методы могут вызывать исключения? Согласно документации, которой я склонен доверять, ни одно исключение при вызове этих методов не генерируется.
На самом деле намутил ты конечно конкретно - честно - никогда еще не видел таких больших нефункциональных блоков Try-Catch
В внешнем Try поставь
Throw ex
Finally
ora_conn.Close()
ora_conn.Dispose()
End Try
Но я бы сделал так:
";Persist Security Info=True;User ID=" + "reporter" + _
"; Password=" + "xxxxxxx" + ";Unicode=False"
Using ora_comm As New OracleClient.OracleCommand()
ora_conn.Open()
End Using
End Using
Код гарантирует освобождение неуправляемых ресурсов вне зависимости от того как пройдет выполнение кода.
Номер ответа: 2
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #2
Добавлено: 17.01.07 12:00
ну во-первых это могут dispose не только от мелкомягких классов, но и от моих собственных - а там я могу код какой угодно воткнуть.
Throw ex
Finally
ora_conn.Close()
ora_conn.Dispose()
End Try
а если у меня ora_conn будет nothing на этом этапе?
Пасиба. Попробую что-то изобразить. Он Dispose сам вызывает что ли? Хорошо бы...
Номер ответа: 3
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #3
Добавлено: 17.01.07 12:08
Throw ex
Finally
ora_conn.Close()
ora_conn.Dispose()
End Try
и кстати после throw ex finally не выполняется.
Номер ответа: 4
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #4
Добавлено: 17.01.07 12:17
Finally должен выполняться в любом случае.. Другое дело что внутри этого блока исключения тоже генерируются и их надо перехватывать. И вызов Dispose (имхо) это лишнее в данной ситуации.. А вообще Using обеспечивает уничтожение объекта после выхода из этого блока..
Номер ответа: 5
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #5
Добавлено: 17.01.07 12:19
А у тебя он не выполняется потому что внутри блока Catch стоит Throw ex, а это по сути тоже самое исключение которое генерируется тобой и нигде не перехватывается..
Номер ответа: 6
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #6
Добавлено: 17.01.07 16:23
Если ты в Dispose воткнул "какоу угодно код" то дополнительный блок Try тебя не спасет от ситуации.
Кстати что касается OracleConnection, утром не досмотрел...
ora_conn.Dispose()
Достаточно сделать Dispose - он сам закрывает соединение.
сори, не досмотрел.
еще раз сори, сказалось 30-часовое отсутствие сна
Гарантировано, что как только выполнение выйдет за пределы блока Using, Dispose будет вызван.
Номер ответа: 7
Автор ответа:
BUMM ®
Вопросов: 8
Ответов: 482
Профиль | | #7
Добавлено: 25.01.07 01:52
Перед тем как закрывать connection прверь состояние:
try
...
...
Catch ex As Exception
msgbox(ex.message)
Finally
If not ((ora_conn is nothing) or (ora_conn.State = ConnectionState.Closed)) then
ora_conn.close()
end if
end try
ora_conn.Close()
ora_conn.Dispose()
А почему ты решил что эти методы могут вызывать исключения? Согласно документации, которой я склонен доверять, ни одно исключение при вызове этих методов не генерируется.
если connection уже закрыт и ты второй раз пытаешься его закрыть, будет исключение.
Номер ответа: 8
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #8
Добавлено: 25.01.07 07:25
MSDN:
поэтому никакого гемороя с проверками не требуется.
Номер ответа: 9
Автор ответа:
BUMM ®
Вопросов: 8
Ответов: 482
Профиль | | #9
Добавлено: 26.01.07 00:19
тоже верно, чего это я стормозил так ???
Номер ответа: 10
Автор ответа:
BUMM ®
Вопросов: 8
Ответов: 482
Профиль | | #10
Добавлено: 26.01.07 00:22
это открывать нельзя 2 раза ...