-1

我有一个执行模拟并不断读取/写入二进制文件的表单应用程序。如果您让它运行,一切都会正常工作。但是,如果表单已关闭/模拟被中止,则文件流未正确关闭 - 使文件处于锁定状态。有没有办法确保所有流都关闭?我尝试了以下 - 但它没有效果......提前非常感谢,T

        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; }
            }
        }
4

3 回答 3

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());
    }
}

请注意,简单地吃例外绝不是一个好主意。如果您不关心是否可以关闭读取器或写入器,请在按照评论中的建议关闭之前检查它是否已初始化。

于 2012-05-11T09:05:53.193 回答
2

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

解释:

StreamReader, StreamWriter, BinaryReader and BinaryWriter当您对它们调用 Dispose 时,所有关闭/处理它们的底层流。如果读取器/写入器只是被垃圾收集,它们不会处理流 - 您应该始终处理读取器/写入器,最好使用using语句。(事实上​​,这些类都没有终结器,也不应该有。)

Personally I prefer to have a using statement for the stream as well. You can nest using statements without braces quite neatly:

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

Even though the using statement for the stream is somewhat redundant (unless the StreamReader constructor throws an exception) I consider it best practice as then if you get rid of the StreamReader and just use the stream directly at a later date, you'll already have the right disposal semantics.

于 2012-05-11T09:08:37.217 回答
1

It is always good to use Using block for the streams, Closing them immediately after use.

于 2012-05-11T09:09:44.987 回答