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):
- Requires you to remember to add the item to the list. (Although you could also say you have to remember to use
using
.) - 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
Differencebetween an Int and an Integer in Java and C#
Saving Any File to in the Database, Just Convert It to a Byte Array
Load an Exe File and Run It from Memory
Creating a Copy of an Object in C#
Passing Values Between Windows Forms C#
Notification When a File Changes
Convert String[] to Int[] in One Line of Code Using Linq
How to Read an Attribute on a Class at Runtime
Create Instance of Generic Type Whose Constructor Requires a Parameter
Recommended Servicestack API Structure
Difference Between Observablecollection and Bindinglist
Differencebetween 'Protected' and 'Protected Internal'