0

SQL イメージをファイルにエクスポートする際に問題が発生しています。最初にリストを初期化します。MyRecord は、GraphicName と Graphic プロパティを持つクラスです。リストを調べて MyRecord.Graphic をディスクに保存しようとすると、「System.ObjectDisposedException」タイプの最初の例外が発生します。これは、バイトをデータベースからイメージに変換するときに、MemoryStream でusingステートメントを使用したためだと思います。using文が使えず、全て動くのですが、最大6,000レコードでメモリ使用量・メモリリークが気になります。バイトを画像に変換する別の方法はありますか、またはこれを行うためのより良い設計はありますか?

... prior code
using (SqlDataReader reader = sqlCommand.ExecuteReader())
{
    while (reader.Read())
    {
        MyRecord record = new MyRecord();
        record.GraphicId = reader["GRAPHIC_ID"].ToString();
        record.Graphic = !reader.IsDBNull(reader.GetOrdinal("IMAGE")) ? GetImage((byte[])reader["IMAGE"]) : null;
        records.Add(record);
    }
... more code

private Image GetImage(byte[] rawImage)
{
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream(rawImage))
    {
        Image image = Image.FromStream(ms);
        return image;
    }
}
4

1 に答える 1

6

クラスは基本的にそれ以降のストリームを担当するため、に渡されるストリームを含むステートメントを使用しないでくださいドキュメントから:usingImage.FromStreamImage

イメージの存続期間中、ストリームを開いたままにしておく必要があります。

コードを次のように変更するだけです。

private Image GetImage(byte[] rawImage)
{
    var stream = new MemoryStream(rawImage);
    return Image.FromStream(stream);
}

...しかし、Image後でオブジェクトを破棄するようにしてください。これにより、ストリームが破棄され、メモリをガベージ コレクションできるようになります。その後、メモリ リークは発生しないはずですが、一度に 6000 個の画像すべてを実際にメモリにロードできるかどうかを調べる必要があります。

(オブジェクトを破棄しない場合、Imageオブジェクトは何らかの時点でファイナライズされる可能性がありますが、決定論的に破棄することをお勧めします。)

于 2013-05-09T19:31:47.817 に答える