2016-05-26 12 views
0

Visual Studio 2013でソリューションのRUnコード分析を選択すると、「CA2202オブジェクトを複数回は処理しないでください。メソッド 'RoboReporterSQL.SaveReportDataToDB(string、string)」にオブジェクト' fs 'を複数回配置できます。 。。」あなたがオブジェクト上に複数の時間を設ける呼び出すべきではありませんSystem.ObjectDisposedExceptionの発生を回避するためにこの表面的に無意味なコード解析の警告に耳を傾けるべきですか?

コードの指示された行は、次のとおりです。

fs.Close(); 

そして、ここでは、コンテキスト内のコードです:

internal static void SaveReportDataToDB(string filename, string 
RESTFilename) 
    { 
     if (RecordAlreadyExists(RESTFilename)) return; 
     string EXCEL_FILE = "application/vnd.ms-excel"; 
     DateTime begDate = 
RoboReporterConstsAndUtils.GetBeginDate(RESTFilename); 
     DateTime endDate = 
RoboReporterConstsAndUtils.GetEndDate(RESTFilename); 

     var fs = new FileStream(filename, FileMode.Open, FileAccess.Read); 
     BinaryReader br = new BinaryReader(fs); 
     Byte[] bytes = br.ReadBytes((Int32)fs.Length); 
     br.Close(); 
     fs.Close(); 

     using (var sqlConn = new SqlConnection(CPSConnStr)) 
     { 
      var insertStr = "INSERT INTO ReportsGenerated (FileBaseName, 
ContentType, BinaryData, BeginDate, EndDate) " + 
          "VALUES (@FileBaseName, @ContentType, 
@BinaryData, @BeginDate, @EndDate)"; 

      using (var insertRptsGenerated = new SqlCommand(insertStr)) 
      { 
       insertRptsGenerated.Connection = sqlConn; 
       insertRptsGenerated.Parameters.Add("@FileBaseName", 
SqlDbType.VarChar, 100).Value = RESTFilename; 
       insertRptsGenerated.Parameters.Add("@ContentType", 
SqlDbType.VarChar, 50).Value = EXCEL_FILE; 
       insertRptsGenerated.Parameters.Add("@BinaryData", 
SqlDbType.Binary).Value = bytes; 
       insertRptsGenerated.Parameters.Add("@BeginDate", 
SqlDbType.DateTime).Value = begDate; 
       insertRptsGenerated.Parameters.Add("@EndDate", 
SqlDbType.DateTime).Value = endDate; 
       sqlConn.Open(); 
       insertRptsGenerated.ExecuteNonQuery(); 
      } 
     } 
    } 

"fs.Close();を呼び出すと、警告がFileStreamが2回クローズしていると主張しています。

私は確実にそれを否定していませんが、私はそれが他の場所に閉じ込められているとは思わないので、質問します。

結局のところ、それは "使用中"ブロックではないので、どのように閉じていますか?

質問:私は本当にそのコード行( "fs.Close();")を削除する必要がありますか?

注:Resharperはこのことについて、「fs.Close();」と言っていませんでした。それはどちらの方法でも警告フラグを立てません。

+2

あなたはそれを2回閉じています。 BinaryReaderを閉じるときに閉じています - それはまた、下にあるストリームを閉じます。そして、あなたは本当に使用している必要があります –

+2

これは死ぬために議論されており、あなたの評判だけが生きている質問を維持します... –

+0

私はこのケースではエラーの言葉だけをオフになっているのだろうかと思います。 'BinaryReader'を閉じることで' FileStream'が破棄された場合、破棄されたオブジェクトの 'Close'メソッドにアクセスすると' ObjectDisposedException'がスローされることがあります。 –

答えて

4

このストリームを明示的に閉じるべきではありません。usingブロックを使用してください。

とにかく、ストリームが既に閉じられているため警告が表示されます。リーダ/ライタがストリームをラップすると、ストリームを閉じると、ストリームも閉じます。読者/ライターの中にはストリームを開いたままにするオプションがあります。

具体的なケースでは、Fileクラスで利用可能ないくつかの方法を使用して、2つの鳥を1つの石で殺すことができます。ファイルを読むにはFile.ReadAllBytes()を使用することを検討してください。

3

それはまだ非常に役に立たない警告だと付け加えたいと思います。私はIDisposableの実装を見たことがなく、複数回Disposeを呼び出すとObjectDisposedExceptionをスローします。次が書き込まれ、実際にIDisposable.Disposeのドキュメントで:

オブジェクトのDisposeメソッドが複数回呼び出された場合、オブジェクトは最初のものの後にすべての呼び出しを無視しなければなりません。オブジェクトは、そのDisposeメソッドが複数回呼び出された場合、例外をスローしてはなりません。

ただし、ストリームではなくDisposeを呼び出します。この場合は同じですが、一般的には呼び出すべきではありません廃棄されたオブジェクトのメソッドを廃棄しないでください。少なくともDisposeに変更してください。

+0

「BinaryReader」が閉じられているため、「FileStream」が破棄される可能性があるのではないかと思います。この警告は、すでに配置された 'FileStream'(fs)オブジェクトにアクセスすると' ObjectDisposedMethod'が発生する可能性があることを示しています。つまり、 'FileStream'を破棄し、' Close'メソッドを呼び出すとどうなりますか? –

+0

何も起こりません。しかし、何か他のことをしようとすると(読み込み/書き込みなど)、ObjectDisposedExceptionがスローされます。私は何年も前に何の問題もなく、このパターンを使用しています(2つのブロックを使ってリーダとストリームの両方を処分しています)。 – Evk

+0

私は2回の処分を意味しません。私はすでに配置されたオブジェクトの 'Close'メソッドにアクセスすることはできませんでしたか? –

関連する問題