I wonder if the object created in the usingstatement gets disposed if I perform a return or throw operation. Example as follows.
using(SomeClass thing = new SomeClass())
{
...
if(condition)
return;
...
}
Will the above get confused or is GC to be trusted here?
Yes, it will. The using statement will result in a finally block being created. A finally block's code will be run even if an exception is thrown in the related try block, or if there is a return statement in that try block.
There are only a few exceptions that can cause a finally block's code to not be executed, and they are all listed here, but my guess is that in your situation you'll be able to live with those consequences.
using is the equivalent of try-finally so, yes, it does.
dispose if it is implemented will always get called. Its the equivalent of calling dispose in a finally block.
It will dispose, yes. It will create a finally block in the CIL code.
Yes, because using is extended into a try finally by the compiler. The dispose will occur inside the finally block. Also, the finally will contain a test to check if the variables in the using are null (in case there are exceptions on the constructors).
When writing a using statement:
using(SomeClass thing = new SomeClass())
{
//...
if (condition)
return;
//...
}
this will result in the following code:
SomeClass thing;
try
{
thing = new SomeClass();
//...
if (condition)
return;
//...
}
finally
{
if(thing != null)
{
thing.Dispose();
}
}
So all object declared using ( /* HERE */ ) will get disposed automatically. Objects declared inside the {} won't.
But you can of course nest (or stack) using statements:
using (var thing = new SomeClass())
using (var another = new Another())
using (var somethingElse = new Whatever())
{
//...
}
which in turn of course is just the syntactic sugar for writing
using (var thing = new SomeClass())
{
using (var another = new Another())
{
using (var somethingElse = new Whatever())
{
//...
}
}
}
because when a statement is followed by just one block of code (in this case another using-block) you can skip the curly braces...
When using two or more objects of the same type you can chain the declaratio within the using-statement:
using (MemoryStream stream = new MemoryStream(), stream2 = new MemoryStream())
{
//...
}
(Thanks to #Gratzy for pointing that out)
For me, the question does not match with the details, and the details have been addressed here a bunch but not the title question...
Does using dispose all the the objects declared in it?
NO, it does not. It only calls Dispose() for the object(s) in its declaration. It does not call Dispose() for objects declared in it.
I usually see this kind of thing in code
using(var sqlConn = new SqlConnection("connStr"))
using(var sqlCmd = new SqlCmd("CmdText", sqlConn))
{
sqlConn.Open();
var reader = sqlCmd.ExecuteReader();
while (reader.Read())
{
//stuff is done
}
}
This will dispose and close both sqlConn and sqlCmd when the scope is complete for those but the reader that was declared in the using scope does not have Dispose() automatically called for it .
Related
I have the following code, where I want to immediately dispose of ApplicationDbContext instance:
using (var context = ApplicationDbContext.Create())
{
MyRepository myRespository = new MyRepository(context);
myRepository.ReadData();
}
If C# garbage collector wants to immediately dispose of ApplicationDbContext, it would have to immediately dispose of MyRepository as well, because it has a reference to ApplicationDbContext? Is this actually happening?
Or do I need to write my code like below to ensure ApplicationDbContext is Disposed, immediately?
using (var context = ApplicationDbContext.Create())
using (MyRepository myRespository = new MyRepository(context))
{
myRepository.ReadData();
}
Your second block of code is right.
One using clause is applied to one declaration.
Wat you wrote here:
using (var context = ApplicationDbContext.Create())
using (MyRepository myRespository = new MyRepository(context))
{
myRepository.ReadData();
}
Is the same as:
var context = ApplicationDbContext.Create();
try
{
var myRespository = new MyRepository(context);
try
{
myRepository.ReadData();
}
finally
{
myRepository.Dispose();
}
}
finally
{
context.Dispose();
}
That's what the compiler generate for you, therefore you do not need to worry about writing such a heavy and repetitive thing which is a possible source of error and bugs.
In the first code, myRespository is not disposed.
This question already has answers here:
Does the using statement dispose only the first variable it create?
(6 answers)
Closed 9 years ago.
This may be answered elsewhere, but after doing a bit of searching I didn't find much on the subject outside of the normal using context.
I am curious if all objects created in a using block will be disposed of as well as the original object.
Here is the context:
Normally I would do something like this:
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(commandText, conn))
{
//Do everything I need to here
}
I know that both conn and cmd go out of scope at this point and are disposed of because of the lovely using keyword.
I am curious if the same disposal rules would apply to the following statement:
using (var cmd = new (SqlCommand(commandText, new SqlConnection(ConnectionString)))
{
//Do everything I need here
}
Would the SqlConnection object that was created inline in the using statment be disposed of when cmd goes out of scope and is disposed of because it's associated with the object?
Also which would be syntactically preferred? I personally think the 2nd is cleaner, but I understand readability may come to play here as well.
For your second code, Dispose won't be called on SqlConnection instance when flow leaves using block unless SqlCommand.Dispose() do that internally (and no, it doesn't).
According to specification (8.13), using (ResourceType resource = expression) statement is transformed into:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if(resource != null)
((IDisposable)resource).Dispose();
}
}
In your code, resource is SqlCommand, and that's the one Dispose is called on.
No.
using statements only apply to the resources declared directly in the statement; not to other allocations in the initializer.
You need a separate using statement for each resource.
According to MSDN, this code:
using (var temp = obj)
{
// ...
}
Translates to (including the extra curly braces to limit the scope):
{
var temp = obj;
try
{
// ...
}
finally
{
if (temp != null)
((IDisposable)temp).Dispose();
}
}
As you can see, if you substitute obj for new SqlCommand(commandText, new SqlConnection(ConnectionString)) then only the SqlCommand gets properly disposed.
{
SqlCommand temp = new SqlCommand(commandText,
new SqlConnection(ConnectionString));
try
{
// ...
}
finally
{
if (temp != null)
((IDisposable)temp).Dispose();
}
}
So, the SqlConnection won't get disposed unless the disposed SqlCommand does that. But it doesn't, and it shouldn't: it didn't create the object, therefore it must not destroy it either.
Certainly there are already answers that explains this correctly. This is covered by the specification as mentioned by others.
But you could just try it out. Here is an example:
static class Program
{
static void Main()
{
using (new DisposeMe("outer", new DisposeMe("inner", null)))
{
Console.WriteLine("inside using");
}
Console.WriteLine("after using scope");
}
}
class DisposeMe : IDisposable
{
public readonly string name;
public DisposeMe(string name, object dummy)
{
this.name = name;
}
public void Dispose()
{
Console.WriteLine("'Dispose' was called on instance named " + name);
}
}
Output:
inside using
'Dispose' was called on instance named outer
after using scope
(Of course if you nest two using statements, as in using (var inner = new DisposeMe("inner", null))
{
using (new DisposeMe("outer", inner))
{ ... } }, the Dispose method is called on both objects.)
I've noticed that the level of nested using statements has lately increased in my code. The reason is probably because I use more and more of async/await pattern, which often adds at least one more using for CancellationTokenSource or CancellationTokenRegistration.
So, how to reduce the nesting of using, so the code doesn't look like Christmas tree? Similar questions have been asked on SO before, and I'd like to sum up what I've learnt from the answers.
Use adjacent using without indentation. A fake example:
using (var a = new FileStream())
using (var b = new MemoryStream())
using (var c = new CancellationTokenSource())
{
// ...
}
This may work, but often there's some code between using (e.g. it may be too early to create another object):
// ...
using (var a = new FileStream())
{
// ...
using (var b = new MemoryStream())
{
// ...
using (var c = new CancellationTokenSource())
{
// ...
}
}
}
Combine objects of the same type (or cast to IDisposable) into single using, e.g.:
// ...
FileStream a = null;
MemoryStream b = null;
CancellationTokenSource c = null;
// ...
using (IDisposable a1 = (a = new FileStream()),
b1 = (b = new MemoryStream()),
c1 = (c = new CancellationTokenSource()))
{
// ...
}
This has the same limitation as above, plus is more wordy and less readable, IMO.
Refactor the method into a few methods.
This is a preferred way, as far as I understand. Yet, I'm curious, why would the following be considered a bad practice?
public class DisposableList : List<IDisposable>, IDisposable
{
public void Dispose()
{
base.ForEach((a) => a.Dispose());
base.Clear();
}
}
// ...
using (var disposables = new DisposableList())
{
var a = new FileStream();
disposables.Add(a);
// ...
var b = new MemoryStream();
disposables.Add(b);
// ...
var c = new CancellationTokenSource();
disposables.Add(c);
// ...
}
[UPDATE] There are quite a few valid points in the comments that nesting using statements makes sure Dispose will get called on each object, even if some inner Dispose calls throw. However, there is a somewhat obscure issue: all nested exceptions possibly thrown by disposing of nested 'using' frames will be lost, besides the most outer one. More on this here.
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());
// ...
}
You should always refer to your fake example. When this is not possible, like you mentioned, then it is very likely that you can refactor the inner content into a separate method. If this also does not make sense you should just stick to your second example. Everything else just seems like less readable, less obvious and also less common code.
I would stick to the using blocks. Why?
It clearly shows your intentions with these objects
You don't have to mess around with try-finally blocks. It's error prone and your code gets less readable.
You can refactor embedded using statements later (extract them to methods)
You don't confuse your fellow programmers including a new layer of abstractions by creating your own logic
Your last suggestion hides the fact that a, b and c should be disposed explicitly. That`s why it's ugly.
As mentioned in my comment, if you'd use clean code principles you wouldn't run into these problems (usually).
Another option is to simply use a try-finally block. This might seem a bit verbose, but it does cut down unnecessary nesting.
FileStream a = null;
MemoryStream b = null;
CancellationTokenSource c = null;
try
{
a = new FileStream();
// ...
b = new MemoryStream();
// ...
c = new CancellationTokenSource();
}
finally
{
if (a != null) a.Dispose();
if (b != null) b.Dispose();
if (c != null) c.Dispose();
}
As it is, I tried error-proofing my code and ended up making it look quite messy.
I have a function set up to read a certain type of file. I want the function to return false if there was a problem, or true if everything worked. I'm having trouble figuring out how to structure everything.
I have an initial try-catch block that tries to open a file stream. After that though, I have certain other checks I make during the reading process such as file size and values at certain offsets. The way I set it up was with if else statements. Such as:
if(condition){
}
else{
MessageBox.Show("There was an error");
br.Dispose();
fs.Dispose();
return false;
}
...br being the binary reader and fs the filestream. There are many blocks like this, and it seems like bad practice to write the same thing so many times. The first thing that comes to mind is to wrap the entire thing in a try-catch statement and throw exceptions instead of using the if else blocks. I remember when reading about try-catch statements that it's good to have them, but not to wrap everything with them. To be honest, I still don't completely understand why it would be bad practice to wrap everything in try catch statements, as they only have an effect when there's an error, in which case the program is going south anyway...
Also, do I have to close the binary reader and file stream, or will closing one close the other? Is there any way to use them without having to dispose of them?
How about making use of the using keyword? this wraps your use of an IDisposable in a try - finally block;
bool success = true;
using(var fs = new FileStream(fileName, FileMode.Create)))
using(var br = new BinaryReader(fs))
{
// do something
success = result;
}
return success;
The nested using blocks will ensure that both the filestream and binary reader are always properly closed and disposed.
You can read more about using in MSDN. It makes the use of IDisposable a little neater, removing the need for explicit excpetion handling.
Regarding your statement:
I remember when reading about try-catch statements that it's good to
have them, but not to wrap everything with them.
I always use the simple rule that if I cannot handle and recover from an exception within a particular block of code, don't try to catch it. Allow the exception to 'bubble up' the stack to a point where it makes more sense to catch it. With this approach you will find that you do not need to add many try-catch blocks, you will tend to use them at the point of integration with services (such as filesystem, network etc ...) but your business logic is almost always free of exception handling mechanisms.
Just use the using keyword for your disposable objects. Within the block of the using keyword you can throw exceptions or return without having to worry about disposal; it will happen automagically for you.
try-catch blocks are not a very good idea only because there exists a much better alternative: the try-finally blocks. But the using keyword is even better because it essentially expands into a try-finally block and it takes care of object disposal.
Closing the file stream will also close the binary reader, and so will disposing of them do. Why do you want to use them without disposing them? Disposing them is better, and disposing them via using is the best thing to do.
I think the best way to make sure filestreams are disposed is to wrap their usage with the following using block
using (FileStream)
{
....
}
Yes, it is bad practice.
Instead of returning booleans that indicate whether a problem occurred or not, you should throw exceptions. Example:
if (headNotValid)
throw new Exception("Header was not valid");
In some cases it may be advisable to make a new exception class.
When working with classes that inherit from IDisposable you should use the using directive.
using (var stream = new FileStream(filename))
{
}
That guarantees, that your stream is disposed, even if a exception is thrown within the using block.
In summary, I would prefer something like this:
private void string ParseFile(string filename)
{
using (var stream = new FileStream(filename))
{
if (somethingNotValid)
throw new Exception(...);
return ...;
}
}
And in your main:
{
try
{
var value = ParseFile(filename);
}
catch (Exception)
{
Console.WriteLine(..);
}
}
Use the using keyword. With using you can rewrite something like this:
public static int CountCars()
{
SqlConnection conn = new SqlConnection(connectionString);
try
{
SqlCommand cmd = conn.CreateCommand();
conn.Open();
try
{
cmd.CommandText = "SELECT COUNT(1) FROM Carsd";
return (int)cmd.ExecuteScalar();
}
finally
{
if(cmd != null)
cmd.Dispose();
}
}
finally
{
if(cmd != null)
conn.Dispose();
}
}
into this:
public static int CountCars()
{
using(SqlConnection conn = new SqlConnection(connectionString))
using(SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT COUNT(1) FROM Carsd";
return (int)cmd.ExecuteScalar();
}
}
Both code snippets will produce exactly the same IL code when compiled. The examples are from http://coding.abel.nu/2011/12/idisposable-and-using-in-c/ where I wrote some more details about using and IDisposable.
I am trying to come up myself with an acceptable pattern for data reading from DB using Enterprise Library. How do you consider the following pattern (I mean, the null-check in the finally block)?
IDataReader NewReader = null;
try
{
NewReader = (SqlDataReader)(SqlDatabase.ExecuteReader(SqlCommand));
/* Do some work with NewReader. */
NewReader.Close();
}
catch /* As much 'catch' blocks as necessary */
{
/* Handle exceptions */
}
finally
{
if (!ReferenceEquals(NewReader, null))
{
NewReader.Dispose();
}
}
Is this null-check acceptable, or is there a more elegant way of solving this problem?
I would use if(NewReader == null). It's the default way of checking for null. Your way of doing it is the same, but it looks strange and thus might confuse people.
Besides: Why don't you use using? Makes your code a lot cleaner:
try
{
using(IDataReader NewReader = (SqlDataReader)(SqlDatabase.ExecuteReader(SqlCommand)))
{
/* Do some work with NewReader. */
}
}
catch /* As much 'catch' blocks as necessary */
{
/* Handle exceptions */
}
It is the same as:
if (NewReader != null) ...
which I would prefer from a styling point of view.
Update:
As NewReader seemingly implements IDisposable, just wrap it in a using construct.
Example:
using (var r = new ReaderSomething())
{
try
{
}
catch {}
}
I would prefer using the "using" block as:
using(<your reader object>)
{
//read data from reader
}
Just to add a bit of detail to what people have said above...
Use a using block as, regardless of whether an exception occurs or not, the Dispose method will automatically be called due to implementations of IDataReader having to also implementing IDisposable.