none
Should I flush and close these objects?

    Question



  • We are having problems that may be attributable to a objects not being completely disposed of/cleaned up between executions of certain methods in an exe and its ancillary DLL. Specifically, Null Reference Exceptions are occurring after objects are reused - the first time through a particular operation, it works, but the second time - like Swiss clockwork - it fails...which requires a "warm boot" (handheld device), and then back to the same pattern - fine the first time, failure the second.

    Is this sort of code (in the finally block) helpful, or just a wasted trip through the carpal tunnel:

    StreamReader sr          = null;
    FileStream   fStream     = null;
    BinaryReader rdr         = null;
    BinaryWriter bwrtr       = null;
    . . .
    try {
      // a flurry of activity, much spinning of wheels and whirling of virtual dervishes
    }
    finally {
    	if (null != sr)
    	{
    		sr.Close();
    	}
    	if (null != fStream)
    	{
    		fStream.Flush();
    	}
    	if (null != rdr)
    	{
    		rdr.Close();
    	}
    	if (null != bwrtr)
    	{
    		bwrtr.Flush();
    	}
    }

    ?

    Friday, June 28, 2013 10:54 PM

All replies

  • Hi,

    The code you use should be use, to close the different objects.

    You also should use Dispose method when it is applicable


    João Sousa (MCTS) Senior Software Engineer

    Friday, June 28, 2013 11:49 PM
  • If you mean I should use "using" yes, I agree, but in this case there are many static objects like readers and writers that are called from other places - they are opened and need to be kept open outside of the method in which there were opened (that's how it was "architected").

    So I may need to explicitly call Close() or Flush() on these objects, but I can't use using.

    Friday, June 28, 2013 11:58 PM
  • "So I may need to explicitly call Close()"

    It's not may, it's must. If you open a stream then you have to close it sooner or later. If you don't close it then GC will close it at some point but that may take a while and may cause issues like not being to open the file again because it is already opened.

    As for Flush that really depends on your code but in my experience it is rarely necessary. It's interesting that you're closing 2 objects and flushing 2 others, I get that you want to continue writing to the flushed objects?

    And for the sake of completeness:

    • Close and Dispose do the same thing and they also imply a Flush
    • if you use try/finally you can usually use using instead too, "kept open outside of the method" is irrelevant.
    Saturday, June 29, 2013 7:01 AM
    Moderator
  • Thanks, Mike.

    I call Close() on two because they did not have a Flush() available; maybe because I'm using a prehistoric version of .NET (1.1, on VS2003).

    Saturday, June 29, 2013 1:41 PM
  • It is never a good design to leave a reader, file, DBConnection or similar thing open any line longer then absolutely needed. Splitting the opening, using and closing/diposing of them into seperate codepart is a surefire way to forget to close them and cause serious havok.

    The only save way to use umanaged resources is this:

    using(var myUnmanagedResource = /*create an instance*/){
      //do the stuff you need to do
    }

    Leaving something that uses umanaged resources undisposed/open is bound to fall on it's face sooner or later.


    Let's talk about MVVM: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b1a8bf14-4acd-4d77-9df8-bdb95b02dbe2

    Saturday, June 29, 2013 3:08 PM
  • Yes, I know, but I didn't design it; we're just trying to get it to limp along for awhile before being replaced by a modern app.
    Saturday, June 29, 2013 3:25 PM
  • If you mean I should use "using" yes, I agree, but in this case there are many static objects like readers and writers that are called from other places - they are opened and need to be kept open outside of the method in which there were opened (that's how it was "architected").

    So I may need to explicitly call Close() or Flush() on these objects, but I can't use using.

    Ah, the misuse of static objects ... gotta love it! NOT!

    I've unfortunately encountered similar misuse of statics in apps not "architected" by myself or some other competent person. Your workaround may be sufficient. Have you tried it? Since your errors appear "like clockwork", I would think it'd be an easy thing to test.

    I'd also add a few other static methods that do all that closing/flushing stuff. Since the readers, writers, etc. are all static, might as well have static methods to close them too.


    ~~Bonnie Berent DeWitt [C# MVP]

    geek-goddess-bonnie.blogspot.com

    Saturday, June 29, 2013 3:52 PM
    Moderator
  • That doesn't make sense, why would you want to call flush on a reader? No version of .NET has Flush on "reader"objects.

    Monday, July 01, 2013 7:53 AM
    Moderator
  • That's true; it doesn't; I was just in "Flush() mode" at the time.
    Monday, July 01, 2013 1:37 PM