Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: как правильно работать с try catch и dispose Добавлено: 17.01.07 07:49  

Автор вопроса:  Neco | Web-сайт: neco.pisem.net | ICQ: 247906854 
глупый вопрос, но просто сейчас я ромажу вот такие конструкции:
    Private Sub RightDbWork()
        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 - я ведь ещё и не закрываю коннект, если происходит исключение после его открытия.
Т.е. получается, что по-хорошему надо накручивать это:
    Private Sub RightDbWork()
        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.Close()
                    ora_conn.Dispose()

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

На самом деле намутил ты конечно конкретно - честно - никогда еще не видел таких больших нефункциональных блоков Try-Catch

В внешнем Try поставь
        Catch ex As Exception
            Throw ex
        Finally
            ora_conn.Close()
            ora_conn.Dispose()
        End Try


Но я бы сделал так:

        Using ora_conn As New OracleClient.OracleConnection(";Data Source=" + "bittl" + _
                                                                  ";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-сайт: neco.pisem.net
 Профиль | | #2
Добавлено: 17.01.07 12:00
А почему ты решил что эти методы могут вызывать исключения?

ну во-первых это могут dispose не только от мелкомягких классов, но и от моих собственных - а там я могу код какой угодно воткнуть.

Catch ex As Exception
            Throw ex
        Finally
            ora_conn.Close()
            ora_conn.Dispose()
        End Try

а если у меня ora_conn будет nothing на этом этапе?
Код гарантирует освобождение неуправляемых ресурсов вне зависимости от того как пройдет выполнение кода

Пасиба. Попробую что-то изобразить. Он Dispose сам вызывает что ли? Хорошо бы...

Ответить

Номер ответа: 3
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #3
Добавлено: 17.01.07 12:08
Catch ex As Exception
            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 не только от мелкомягких классов, но и от моих собственных - а там я могу код какой угодно воткнуть.

Если ты в Dispose воткнул "какоу угодно код" то дополнительный блок Try тебя не спасет от ситуации.

Кстати что касается OracleConnection, утром не досмотрел...

    ora_conn.Close()
    ora_conn.Dispose()

Достаточно сделать Dispose - он сам закрывает соединение.

а если у меня ora_conn будет nothing на этом этапе?

сори, не досмотрел.

и кстати после throw ex finally не выполняется.

еще раз сори, сказалось 30-часовое отсутствие сна :(

Пасиба. Попробую что-то изобразить. Он Dispose сам вызывает что ли? Хорошо бы...

Гарантировано, что как только выполнение выйдет за пределы блока 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:

An application can call Close more than once without generating an exception.


поэтому никакого гемороя с проверками не требуется.

Ответить

Номер ответа: 9
Автор ответа:
 BUMM ®



Вопросов: 8
Ответов: 482
 Профиль | | #9 Добавлено: 26.01.07 00:19
тоже верно, чего это я стормозил так ???

Ответить

Номер ответа: 10
Автор ответа:
 BUMM ®



Вопросов: 8
Ответов: 482
 Профиль | | #10 Добавлено: 26.01.07 00:22
это открывать нельзя 2 раза ...

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам