Search code examples
c#filestreambinaryreaderbinarywriter

BinaryReader or Writer.Close() is not closing properly C#


I have a form application that performs a simulation and constantly reads/writes a binary file. Everything works fine if you let it run through. However, if the form is closed/ the simulation is aborted the file-stream is not closed properly - leaving the file locked. Is there a way to make sure all streams closed? I tried the following - but it has no effect... Thanks a lot in advance, 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; }
            }
        }

Solution

  • Are you sure you know what the continue keyword is for? Please note that this continues with the next loop, not the next block of code. So if an exception occurs closing EnvBinRead, you will not enter the block to close EnvBinWrite, but continue with the next item from AllBldgs.

    To eat all exceptions and still try to close all the binary writers, you'd write:

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

    Please note that simply eating the exceptions is never a good idea. If you don't care whether the reader or write could be closed, check whether it has been initialized before closing it as suggested in the comments.