2012-05-11 40 views
-1

我有一个表单应用程序,它执行模拟并不断读取/写入二进制文件。如果你让它通过,一切正常。但是,如果表单被关闭/模拟被中止,则文件流没有被正确关闭 - 文件被锁定。 有没有办法确保所有的流都关闭?我尝试以下 - 但它没有任何效果... 非常感谢提前, 牛逼BinaryReader或Writer.Close()未正确关闭C#

 public BinaryWriter BinWrite; 
     public BinaryReader BinRead; 

     public BinaryWriter EnvBinWrite; 
     public BinaryReader EnvBinRead;  

public void theForm_FormClosing(object sender, FormClosingEventArgs e) 
     { 

      //Close all binary file reader/writers -- crashes if it cannot overwrite files 
      foreach (Building B in AllBldgs) 
      { 
       try 
       { 
        EnvBinRead.Close(); 
       } 
       catch 
       { continue; } 
       try 
       { 
        EnvBinWrite.Close(); 
       } 
       catch 
       { continue; } 
       try 
       { 
        BinRead.Close(); 
       } 
       catch 
       { continue; } 

       try 
       { 
        BinWrite.Close(); 
       } 
       catch 
       { continue; } 
      } 
     } 
+0

是否发生任何异常? – CodeCaster

+0

不是我所知道的.. – timkado

+2

不,因为你把它们都吃掉了。删除try..catch块并查看是否发生。 – CodeCaster

回答

7

你确定你知道continue关键词是什么?请注意,这继续与下一个循环,而不是下一个代码块。因此,如果发生异常时发生关闭EnvBinRead,您将而不是输入该块关闭EnvBinWrite,但继续从AllBldgs下一个项目。

吃所有的异常,并仍试图关闭所有二进制作家,你会写:

foreach (Building B in AllBldgs) 
{ 
    try 
    { 
     EnvBinRead.Close(); 
    } 
    catch (Exception exp) 
    { 
     Console.WriteLine("Closing EnvBinRead failed!" + exp.ToString()); 
    } 

    try 
    { 
     EnvBinWrite.Close(); 
    } 
    catch (Exception exp) 
    { 
     Console.WriteLine("Closing EnvBinWrite failed!" + exp.ToString()); 
    } 

    try 
    { 
     BinRead.Close(); 
    } 
    catch (Exception exp) 
    { 
     Console.WriteLine("Closing BinRead failed!" + exp.ToString()); 
    } 

    try 
    { 
     BinWrite.Close(); 
    } 
    catch (Exception exp) 
    { 
     Console.WriteLine("Closing BinWrite failed!" + exp.ToString()); 
    } 
} 

请注意,只是吃的例外是从未一个好主意。如果您不关心读者或写者是否可以关闭,请按照评论中的建议检查它是否在关闭之前已经初始化。

+0

+1,因为这可能是问题的根源。不过,我建议吃异常是一件坏事,如果'BinRead'可能未初始化,'if(BinRead!= null)BinRead.Close();'会更可取。 – Heinzi

+0

是的,我支持这一点。 –

+0

谢谢!我如何检查是否发生异常? – timkado

2

您应该调用dispose关闭BinaryReader和Writer。

说明:

StreamReader, StreamWriter, BinaryReader and BinaryWriter全部关闭/处置其底层流时,你调用Dispose他们。如果读者/作者只是垃圾收集,他们不会处理流 - 您应该始终处理读者/作者,最好使用using声明。 (事实上​​,这些类都没有终结者,也不应该有终结者。)

我个人更喜欢为流使用一个using语句。您可以嵌套使用语句没有括号很整齐:

using (Stream stream = ...) 
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever)) 
{ 
} 

即使using语句流是有些多余的(除非StreamReader构造函数抛出异常),我认为这是最好的实践,然后,如果你摆脱StreamReader并且在稍后的日期直接使用该流,则您将拥有正确的处置语义。

1

对于流使用Using块总是很好,在使用后立即关闭它们。

+1

其实你并不知道。虽然在您想要在读取/写入数据流后立即关闭数据流时建议使用“使用”,但可能会出现应用程序整个生命周期中需要打开数据流的情况。在这种情况下,“使用”根本无法使用。 –