50

I am not sure whether I need to call Flush() on the used objects if I write something like this:

using (FileStream...)
using (CryptoStream...)
using (BinaryWriter...)
{
    // do something
}

Are they always automatically flushed? When does the using statement flush them and when it doesn’t (if that can happen)?

Palec
  • 12,743
  • 8
  • 69
  • 138
Ben
  • 2,435
  • 6
  • 43
  • 57

2 Answers2

63

As soon as you leave the using block’s scope, the stream is closed and disposed. The Close() calls the Flush(), so you should not need to call it manually.

Palec
  • 12,743
  • 8
  • 69
  • 138
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • end of using calls close? I only know that it disposes the stream, and i call close methode in the end every time. – Felix C Oct 10 '11 at 09:18
  • 9
    That's not necessary, Dispose will always Close the stream, and Close will Flush the stream first. – nos Oct 10 '11 at 09:19
  • 1
    @FelixCzylwik: if end of using was not calling Close, you would have tons of open streams and open SQLConnections out there... :D – Davide Piras Oct 10 '11 at 09:25
  • I always closed them manually right before end of using was reached ;-) – Felix C Oct 10 '11 at 09:29
  • 1
    @FelixC Lots of things which the compiler doesn't need are still helpful in the quest of readability. – Robino Jun 10 '15 at 16:36
  • 1
    Related: [Does Stream.Dispose always call Stream.Close](http://stackoverflow.com/a/911425/2157640) and a [caveat](http://stackoverflow.com/a/1015790/2157640) that implicit flush is just the usual behavior and is not implemented by Stream class itself (so be careful when extending it). – Palec Oct 21 '15 at 11:08
  • @Robino - I used to manually add `close()`, reasoning similarly to you. The problem with that was on a large project, sometimes I or another programmer did not put the close statement. This then led to uncertainty as to whether close "needed to be added" there. Worse, sometimes a programmer felt they needed to do `flush` and then `close`. I ended up removing all the `flush` and `close()` lines where they were not needed. Consistent coding, and knowing how a system works ("Using implies Dispose implies Close implies Flush") are also part of "readability". – ToolmakerSteve Oct 07 '16 at 23:11
-4

It varies, Stream by default does not call Flush() in the Dispose method with a few exceptions such as FileStream. The reason for this is that some stream objects do not need the call to Flush as they do not use a buffer. Some, such as MemoryStream explicitly override the method to ensure that no action is taken (making it a no-op).
This means that if you'd rather not have the extra call in there then you should check if the Stream subclass you're using implements the call in the Dispose method and whether it is necessary or not.

Regardless, it may be a good idea to call it anyway just for readability - similar to how some people call Close() at the end of their using statements:

using (FileStream fS = new FileStream(params))
using (CryptoStream cS = new CryptoStream(params))
using (BinaryWriter bW = new BinaryWriter(params))
{
    doStuff();
    //from here it's just readability/assurance that things are properly flushed.
    bW.Flush();
    bW.Close();
    cS.Flush();
    cS.Close();
    fS.Flush();
    fS.Close();
}
IAmJersh
  • 742
  • 8
  • 25
  • 3
    I'd argue that adding the flush and close calls actively harms readability and maintainability. The using statement is what gives the assurance that the object is properly disposed of, even in case an exception is thrown. – Palec Jan 23 '18 at 15:18
  • @Palec I understand that position, this is a bit of a dividing standard among many developers from what I have seen. – IAmJersh Jan 23 '18 at 15:21
  • @Palec Also, as stated in my answer - streams by default do not call `Flush()` in their dispose methods, meaning that if you're using a non-standard stream created by someone who hasn't considered that then the using statement will not flush the buffer properly. Because of this I'd say that it's a good practice to manually flush - it won't do anything if it isn't needed but if it is then it will ensure buffers are being properly disposed. – IAmJersh Jan 23 '18 at 16:09