0

Visual Studioコード分析がこの小さなコードで警告を出すのはなぜだろうと思います:

byte[] data = File.ReadAllBytes("myImage.png");
using (MemoryStream mem = new MemoryStream(data))
using (Bitmap bmp = new Bitmap(mem))            
{
     // do something with the bitmap
}

エラーは次のとおりです。

オブジェクト'mem'はメソッド内で複数回破棄できます...System.ObjectDisposedExceptionの生成を回避するには、オブジェクトに対してDisposeを複数回呼び出さないでください。

そして、これを修正する方法は?(はい、ファイルから直接ビットマップをロードできますが、実際のプロジェクトでは、複数の画像が1つのファイルに保存される独自のファイル形式があるためMemoryStream、ファイル内の特定の範囲からデータをロードする必要があります)

4

4 に答える 4

6

問題はBitmap、コンストラクターで指定されたストリームの所有権を取得することです。ストリームを破棄します-必要はありませんしたがって、必要なのは次のとおりです。

using (Bitmap bmp = new Bitmap(new MemoryStream(data)))            
{
     // do something with the bitmap
}
于 2012-06-29T19:21:28.407 に答える
1

Reacher-Giltのms-pageへのリンクから、両方の警告が消える解決策にたどり着きました。

        byte[] data = new byte[1000];
        MemoryStream mem = null;
        try
        {
            mem = new MemoryStream(data);
            using (Bitmap bmp = new Bitmap(mem))
            {
                mem = null; // <-- this line will make both warning go away
            }
        }
        finally
        {
            if (mem != null)
            {
                mem.Dispose();
            }
        } 
于 2012-06-29T20:42:10.070 に答える
1

2番目の信頼性警告に関しては、この状況が発生した場合、コード分析は、実行内容に関係なく、CA2000またはCA2202のいずれかで文句を言うようです。これについては複数の不満があります。これがあなたの楽しみのためのものです。

構文の使用に特有であるかどうかを確認するために、usingをtry catchブロックに拡張すると、同じ動作が得られます。

class Program
    {
        static void Main(string[] args)
        {
            byte[] data = {};
            //using (Bitmap bitmap = new Bitmap(new MemoryStream(data)))
            //{ }

            MemoryStream mem = null;
            Bitmap bitmap = null;
            try
            {
                mem = new MemoryStream(data);
                bitmap = new Bitmap(mem);

            }
            catch (Exception)
            {

                throw;
            }
            finally
            {
                if (null!= bitmap ) bitmap.Dispose();                
                // commenting this out will provoke a CA2000.
                // uncommenting this will provoke CA2202.
                // so pick your poison.
                // if (null != mem) mem.Dispose();
            }
        } 
    }

編集:あなた(Jaska)が指摘したように、ビットマップの使用ブロックのメモリストリームに関するインテントにフラグを立てることについてのMicrosoftからのメモがあります:

class Program
    {
        static void Main(string[] args)
        {
            byte[] data = new byte[1000];
            MemoryStream mem = null;
            try
            {
                mem = new MemoryStream(data);
                using (Bitmap bmp = new Bitmap(mem))
                {
                    mem = null; // <-- this line will make both warning go away
                }
            }
            finally
            {
                if (mem != null)
                {
                    mem.Dispose();
                }
            } 
        } 
    }

これが機能することを嬉しく思いますが、同時に、ビットマップのコンストラクターで匿名のメモリストリームを使用するよりも少し醜いです。まぁ。

于 2012-06-29T20:15:38.953 に答える
0

2番目のusingステートメントを入力すると、ビットマップはメモリストリームを「消費」します。ビットマップは、その廃棄を含め、メモリストリームを担当します。使用法について考える場合、これは賢明です。ビットマップのコンストラクターで使用した後(または使用中に)、他の何かにアクセスすることを期待memしますか?おそらくそうではないと思います。

答えは、2つのusingステートメントを統合することですusing (Bitmap bitmap = new Bitmap(new MemoryStream(data)))。これでCAの警告が処理されます。

于 2012-06-29T19:30:39.697 に答える