Nested Using Statements in C#

Nested using statements in C#

The preferred way to do this is to only put an opening brace { after the last using statement, like this:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
{
///...
}

Best practice for nested using statements?

You can remove the indention and curly brackets this way:

using (var fileStream = new FileStream("ABC.pdf", FileMode.Create))
using (var document = new Document(PageSize.A4, marginLeft, marginRight, marginTop, marginBottom))
using (var pdfWriter = PdfWriter.GetInstance(document, fileStream))
{
// code
}

Are nested Using statements useful?

the using block "guarantees disposal of the resource... even in the case of an unhandled exception."

Take that "guarantee" with a grain of salt. Many things can prevent the disposal of the resource. What if the using block contains an infinite loop? Or the block throws an exception, a hostile exception filter higher on the stack goes into an infinite loop and never returns control to the finally block associated with the using statement? Or the block calls Environment.FailFast? There are many, many things that can prevent the disposal from ever running. Never write a program that relies on disposal for its correctness. Disposal is there for politeness, to return scarce resources to the pool for others to use them.

Moreover, let me make sure this point is clear: truly unhandled exceptions are implementation-defined behavior in C#. The using block's finally clause is there to deal with the situation where an exception is thrown inside the using block and then handled somewhere else, not to deal with the situation where an exception is thrown inside the block and never handled. If that happens then it is entirely up to the implementation to determine what happens; the C# language makes a total of zero promises about the behavior of a program that throws an exception that is never handled. The resources might be disposed. They might not. You're in a building that is about to be unexpectedly demolished; do you really want to spend time washing the dishes and putting them away neatly?

Is there any benefit to multiple nested Using blocks?

Yes.

Does a single Using block already guarantee that all of the resources it contains will be disposed?

No. Only the resources that are actually mentioned by a using statement are cleaned up. That's why you nest them.

There are a few cases where technically you don't have to because the inner one takes responsibility for releasing the same resource as the outer one. But it doesn't hurt anything to nest using blocks and it makes it very clear to the reader what is going on. The best practice here is to have one using statement for every resource that you want cleaned up.

Dealing with nested using statements in C#

In a single method, the first option would be my choice. However in some circumstances the DisposableList is useful. Particularly, if you have many disposable fields that all need to be disposed of (in which case you cannot use using). The implementation given is good start but it has a few problems (pointed out in comments by Alexei):

  1. Requires you to remember to add the item to the list. (Although you could also say you have to remember to use using.)
  2. Aborts the disposal process if one of the dispose methods throws, leaving the remaining items un-disposed.

Let's fix those problems:

public class DisposableList : List<IDisposable>, IDisposable
{
public void Dispose()
{
if (this.Count > 0)
{
List<Exception> exceptions = new List<Exception>();

foreach(var disposable in this)
{
try
{
disposable.Dispose();
}
catch (Exception e)
{
exceptions.Add(e);
}
}
base.Clear();

if (exceptions.Count > 0)
throw new AggregateException(exceptions);
}
}

public T Add<T>(Func<T> factory) where T : IDisposable
{
var item = factory();
base.Add(item);
return item;
}
}

Now we catch any exceptions from the Dispose calls and will throw a new AggregateException after going through all the items. I've added a helper Add method that allows a simpler usage:

using (var disposables = new DisposableList())
{
var file = disposables.Add(() => File.Create("test"));
// ...
var memory = disposables.Add(() => new MemoryStream());
// ...
var cts = disposables.Add(() => new CancellationTokenSource());
// ...
}

Any issue with nesting using statements in c#?

There should be no issue with your code as far as I can tell, I have always used nested using statements in the past.

From looking through other questions I believe the problem is with the code analysis tool itself and both CA2000 and CA2202 rules. False positives often occur when using various stream and reader types with using statements.

You should ignore the warnings and continue as alternative methods (such as try/finally) will produce bad code and your code is valid.

Getting rid of nested using(...) statements

You could just do this:

using (var a = new A())
using (var b = new B())
{
/// ...
}

Nesting 'IDisposable's in a single 'using' statement

It depends on the constructor, GZipStream disposes of the stream you passed in when you dispose of it unless you use one of the overloads that takes in a bool and you pass in true to leaveOpen.

However you do run a risk doing this. If GZipStream throws a ArgumentException because the CanRead property of the stream is false the passed in stream does not get disposed of.

Personally I rather not depend on "something not going wrong" and instead usually code defensively and use the 3 statement version.


Edit: Just to be clear, I'm not asking about nesting using statements.
I'm asking whether or not an IDisposable that is created inside
another IDisposable's 'using' statement will be disposed of at the end
of the block. Any explanation on why or why not would be appreciated.

If that is your question then the answer is: No, only the object declared that was assigned to (using var whatever = ...) will be disposed, any other objects created are dependent on the code of whatever the "outer" object is to be implemented to "chain call" the Dispose() methods.

C# nested stream with using statement, should I use two using?

When you create a ZlibStream and pass in MemoryStream it holds a reference to it.

When it's Disposed, it calls Close on that reference, which in turn will hit the Dispose plumbing of abstract Stream class.

protected override void Dispose(bool disposing)
{
try
{
if (!_disposed)
{
if (disposing && (this._baseStream != null))
this._baseStream.Close();
_disposed = true;
}
}
finally
{
base.Dispose(disposing);
}
}

It's worth noting, that a MemoryStream has no unmanaged resources anyway, and actually doesn't need to be Disposed, it doesn't override the Close of the Stream class.

Stream also checks if Dispose has already been called. Meaning in most cases, you only have to Dispose the stream you are working with.

C# - nested using statements redundant?

According to the documentation, The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called. This means using the StreamReader guarantees disposal of the underlying Stream. It does not hold vice versa: disposing only the Stream does not suffice - the StreamReader may be allocating other native resources. So the second sample is not correct.

(using only the StreamReader does not cover the case that the StreamReader constructor can throw. To cover this case, both using's would be needed. Since it only throws for non-readable or null streams, this may not be relevant though.)

In general, you should always dispose on every disposable object. It is part of the IDisposable contract that it does not hurt to dispose an object multiple times, and the overhead of doing so is low.



Related Topics



Leave a reply



Submit