none
OleDbConnectionクローズ時にInvalidOperationExceptionが発生する RRS feed

  • 質問

  • こんにちは

    下記コードを実行して、フォームを閉じると、InvalidOperationExceptionが発生します。

    (新規でWindowsアプリケーションを作成し、フォーム内でClass1をNewしています)

     

    Public Class Form1
        Dim cc As New Class1
    End Class


    Public Class Class1
        Protected mDbAccessor As New DataBaseAccessor

     

        Public Sub New()
            mDbAccessor.DBOpen()
        End Sub

     

        Protected Overrides Sub Finalize()
            mDbAccessor.DBClose()
        End Sub
    End Class


    Public Class DataBaseAccessor
        Dim mCn As System.Data.OleDb.OleDbConnection = Nothing

        Public Sub DBOpen()
            Dim str As String = "Provider=MSDAORA.1;User ID=A;Password=B;Data Source=C;database=DataBase;Persist Security Info=False"
            mCn = New System.Data.OleDb.OleDbConnection(str)
            mCn.Open()
        End Sub

     

        Public Sub DBClose()
            If IsNothing(mCn) = False AndAlso mCn.State = ConnectionState.Open Then
                mCn.Close()     ' <-ここでInvalidOperationException例外発生。「ハンドルが初期化されていません。」
            End If

            mCn = Nothing
        End Sub
    End Class

     

    この現象は、WindowsXP, .NetV2.050727, Oracle9i 環境の複数のパソコンで再現することを確認しています。

    なぜこのような例外が発生するのでしょうか?

     

    2008年1月8日 1:50

回答

  • こんにちは、ファクトです。

    DBConnectionのCloseメソッドのヘルプを参照すると、以下の事が書いてあります。

     

    クラスの Finalize メソッドで、ConnectionDataReader、またはその他のマネージ オブジェクトの Close または Dispose を呼び出すことは避けてください。ファイナライザでは、クラスが直接所有しているアンマネージ リソースだけを解放してください。アンマネージ リソースを一切所有しないクラスの場合は、クラス定義の中に Finalize メソッドを含めないでください。詳細については、「ガベージ コレクション」を参照してください。

     

    おそらくこれが原因ではないかと思います。FormのClosed等で明示的にコネクションを閉じる処理を書くと、うまくいったりしませんか?

     

     

    http://msdn2.microsoft.com/ja-jp/library/system.data.common.dbconnection.close(vs.80).aspx

    2008年1月8日 2:15

すべての返信

  • こんにちは、ファクトです。

    DBConnectionのCloseメソッドのヘルプを参照すると、以下の事が書いてあります。

     

    クラスの Finalize メソッドで、ConnectionDataReader、またはその他のマネージ オブジェクトの Close または Dispose を呼び出すことは避けてください。ファイナライザでは、クラスが直接所有しているアンマネージ リソースだけを解放してください。アンマネージ リソースを一切所有しないクラスの場合は、クラス定義の中に Finalize メソッドを含めないでください。詳細については、「ガベージ コレクション」を参照してください。

     

    おそらくこれが原因ではないかと思います。FormのClosed等で明示的にコネクションを閉じる処理を書くと、うまくいったりしませんか?

     

     

    http://msdn2.microsoft.com/ja-jp/library/system.data.common.dbconnection.close(vs.80).aspx

    2008年1月8日 2:15
  • ファクトさん

    ご回答ありがとうございます。

    Formのボタンクリックイベントでクローズするとうまくいきました

    今後Finalizeメソッドを使う際は気をつけます。

     

    ありがとうございました。

    2008年1月8日 3:36