none
ADODBの使用について RRS feed

  • 質問

  • 既存のプロジェクトがVB.NETなのにSystem.Data.SqlClient.SqlConnectionが使用されていません。

    つまりADO.NETではありません。

     

    環境

    VS2003 VB.NET Framework1.1

    http://support.microsoft.com/kb/318559/ja

    1. Visual Studio .NET プロジェクトを開きます。
    2. [プロジェクト] メニューの [参照の追加] をクリックします。
    3. [参照の追加] ダイアログ ボックスで、[.NET] タブをクリックします。
    4. [コンポーネント名] ボックスの一覧の [adodb] をクリックして [選択] をクリックし、[OK] をクリックします。

    の方法で使用されています。

    ADO PIA で動作しています。(と思っています)

    OLE接続(接続文字列にProvider=SQLOLEDB.1が書かれています )

     

    4.2 ADO.NETによるADOレコードセットの読み込みhttp://www.atmarkit.co.jp/fdotnet/special/vb6tovb2005mig03/vb6tovb2005mig03_01.html

    ※この例は(PIA)でなく(IA)です。

     

    この例と同じ様に

    ADODB.Connection

    ADODB.Recordset
    ADODB.Command
    を使用しています。

     

    Q1

    Marshal.ReleaseComObject対象は下記の3つでよいか教えてください。
    ADODB.Connection
    ADODB.Recordset
    ADODB.Command

    (PIA なのでFields 、 Fieldはがマネージオブジェクトであると思っています)

     

    Q2

    既存のプロジェクトでは3つに対してMarshal.ReleaseComObject
    は行われていません。

    この場合、GC任せになっているのか、残り続けるのかどちらの状態になっているのか教えてください。

     

    2008年5月20日 1:31

回答

  • 自己レス

     

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command
    ADODB.Fields

    ADODB.Field

     

    System.Runtime.InteropServices.Marshal.IsComObjectで調べた所

    True

    True

    True

    False

    False

     

    でした

    ADODB.Fields

    ADODB.Field

    に関しては

    ReleaseComObjectで例外があがります。

     

    なので上記レスの

    -----------------------------------------------------------

    OK例

    dim fields as ADODB.Fields = recordset.Fields

    dim field as ADODB.Field = fields.Item("hogeName")

    dim hogeName as string = Convert.ToString(field.value)

    Marshal.ReleaseComObject(field)
    Marshal.ReleaseComObject(fields)

    Marshal.ReleaseComObject(recordset)

    という事でしょうか?

    その通りです。

    -----------------------------------------------------------

    の箇所は誤りです。

     

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command
    の3つをMarshal.ReleaseComObjectする必要があります。

     

    2008年5月20日 7:38

すべての返信

  •  いくみ さんからの引用

    Q1

    Marshal.ReleaseComObject対象は下記の3つでよいか教えてください。
    ADODB.Connection
    ADODB.Recordset
    ADODB.Command

    (PIA なのでFields 、 Fieldはがマネージオブジェクトであると思っています)

     

    ADOのオブジェクトはすべてマネージオブジェクトにはならないと思います。

    よって、FieldsなどもすべてReleaseComObject対象です。

     

     いくみ さんからの引用

    Q2

    既存のプロジェクトでは3つに対してMarshal.ReleaseComObject
    は行われていません。

    この場合、GC任せになっているのか、残り続けるのかどちらの状態になっているのか教えてください。

    アンマネージなものはGC任せにはなりません。

     

    2008年5月20日 2:15
  • レスありがとうございます。

     

    Q1

    >よって、FieldsなどもすべてReleaseComObject対象です。

    Exlec comの感覚で書きますと

    使用方法としては

     

    NG例 fields,fieldが開放されない。

    dim hogeName as string = Convert.ToString(recordset.Fields.Item("hogeName").Value)

    Marshal.ReleaseComObject(recordset)


    OK例

    dim fields as ADODB.Fields = recordset.Fields

    dim field as ADODB.Field = fields.Item("hogeName")

    dim hogeName as string = Convert.ToString(field.value)

    Marshal.ReleaseComObject(field)
    Marshal.ReleaseComObject(fields)

    Marshal.ReleaseComObject(recordset)

    という事でしょうか?

     

    Q2

    >アンマネージなものはGC任せにはなりません。

    既存のコードは使用する度にメモリリークしているということですね?

     

    2008年5月20日 2:40
  •  いくみ さんからの引用

    OK例

    dim fields as ADODB.Fields = recordset.Fields

    dim field as ADODB.Field = fields.Item("hogeName")

    dim hogeName as string = Convert.ToString(field.value)

    Marshal.ReleaseComObject(field)
    Marshal.ReleaseComObject(fields)

    Marshal.ReleaseComObject(recordset)

    という事でしょうか?

    その通りです。

     

     

     いくみ さんからの引用

    Q2

    >アンマネージなものはGC任せにはなりません。

    既存のコードは使用する度にメモリリークしているということですね?

    メモリリークという状態になっているかどうかは不明(管理対象外)です。

    でも、メモリリークしている前提でいた方が良いかと。

    2008年5月20日 2:57
  • 早々のレスありがとうございます。

     

    現在の私の関わっているプロジェクトはPIAで作られています。

     

    [参照の追加] -[.NET]

    C:\Program Files\Microsoft.NET\Primary Interop Assemblies\ADODB.dll

    (PIA)

    [参照の追加] -[.COM]

    C:\TestProject\obj\Interop.ADODB.dll

    (IA)

     

    http://bbs.wankuma.com/index.cgi?mode=al2&namber=7478&KLOG=19

    >一方、PIA の場合は、Fields や Field がマネージオブジェクトになっているため、
    >これらのオブジェクトについては、ReleaseComObject メソッドの呼び出しが不要です。

    http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=7177&reno=7174&oya=7168&mode=msgview&page=0

    >なお、ADODB.DLL の方は、Fields コレクションや Parameters コレクションなどが
    >マネージオブジェクトになっていますが

    http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=6850&page=120

    >PIA (Adodb.dll)の場合、Fileds コレクション等は COM オブジェクトではありませんが、
    >IA (msado15.dll 等)の場合は COM なので、ReleaseComObject が必要です。

    Q3 上記の掲示板のコメントからすると

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command

    Marshal.ReleaseComObjectが必要ですが

    Fields,Fieldは不要の様に書かれています。

     

    PIAの場合のADODBでアンマネージとマネージオブジェクトを区別する方法

    または、それらに関する記述をMSDNからそれらの情報を探してるのですが、みつかってないです。

    情報お持ちの方 いらっしゃいましたら教えてください。

     

    ------------------------------------------------------------------------------------------

    ADO プライマリ相互運用アセンブリ (primary interop assembly) を使用する。

    http://support.microsoft.com/kb/321415/ja

    ADO が正常に動作するためには、使用するクラスのクラス名の最後に、
    必ず "Class" という単語が含まれている必要があります。次に例を示します。
    ADODB.ConnectionClass
    ADODB.RecordsetClass
    ADODB.CommandClass

    これらのオブジェクトを使用する場合は、この資料で説明した ReleaseComObject を使用して
    COM で参照が解放されるようにします。
    ------------------------------------------------------------------------------------------

    そもそも

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command

    を使用している時点で間違っているのではないかという気がしますが・・・。

    既存のプロジェクトは動作しています。

     

     

    2008年5月20日 4:00
  • 自己レス

     

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command
    ADODB.Fields

    ADODB.Field

     

    System.Runtime.InteropServices.Marshal.IsComObjectで調べた所

    True

    True

    True

    False

    False

     

    でした

    ADODB.Fields

    ADODB.Field

    に関しては

    ReleaseComObjectで例外があがります。

     

    なので上記レスの

    -----------------------------------------------------------

    OK例

    dim fields as ADODB.Fields = recordset.Fields

    dim field as ADODB.Field = fields.Item("hogeName")

    dim hogeName as string = Convert.ToString(field.value)

    Marshal.ReleaseComObject(field)
    Marshal.ReleaseComObject(fields)

    Marshal.ReleaseComObject(recordset)

    という事でしょうか?

    その通りです。

    -----------------------------------------------------------

    の箇所は誤りです。

     

    ADODB.Connection
    ADODB.Recordset
    ADODB.Command
    の3つをMarshal.ReleaseComObjectする必要があります。

     

    2008年5月20日 7:38
  • 誤回答失礼致しました。

    そして、検証及び検証報告ありがとうございます。

     

    2008年5月21日 0:30