Let's say I create a disposable object in a method, but I will call a using out of the method. Is then everything disposed in this method?
using(DbConnection connection = new DbConnection("myConnection"){
SomeMethod();
}
public void SomeMethod(){
var stream = new MemoryStream()
// ... Do something with the stream ...
}
Is the stream created in the 'SomeMethod' then disposed?
No, it won't be. Only the reference explicitly specified in the using statement will be disposed.
In this case, only connection will be disposed after the code execution leaves the using block. You'll need to also wrap var stream = .. in a using block, or manually dispose it.
when we use Using keyword,it will call dispose method of object which is created in
using(Form m =new Form()) bracket. so remember we have to dispose manually if anything to dispose in the scope which is defined by {}
Example:
using(Form test =new Form())//test object will disposed by using at end of scope
{//Scope start
//code written here or created new object are not disposed by using
//Scope End
}
Related
Can you assign to a variable instantiated in a using statement before it is disposed at the end. E.g.
using (TempObj temp = new TempObj())
{
temp.doStuff(......);
realObj = temp; // <-------- Is this line ok?
}
If not why can't you?
Edit: I mean what will happen to realObj in this situation
It is possible, but realObj will hold an instance of a disposed object.
Do not use variables created in using() outside the using block.
When an object is created and used only within the scope of a using statement, is it disposed of during the disposal of its enclosing IDisposable instance? If not, why wouldn't it be?
For instance, when using Dapper I've often created an anonymous object within the scope of the SqlConnection with the impression that it will be disposed of sooner - however I recently read something to the contrary.
using (var connection = new SqlConnection("Connection String"))
{
var parameters = new
{
Message = "Hello world!"
};
connection.Execute("INSERT INTO...", parameters);
}
Your using statement is essentially equivalent to:
var connection = new SqlConnection("Connection String");
try
{
var parameters = new
{
Message = "Hello world!"
};
}
finally
{
if (connection != null)
{
((IDisposable)connection).Dispose();
}
}
As you can see, there is no reason why any other IDisposable instance created inside the try block be disposed automatically for you. If you do need to ensure other objects are disposed then simply nest using statements:
using (var connection = new SqlConnection("Connection String"))
{
using (var otherDisposableObject = new ....)
{
} //otherDisposableObject disposed
} //connection disposed
If excessive nesting gets in the way of readability, then you can simply write the using statements as follows:
using (var connection = new SqlConnection("Connection String"))
using (var otherDisposableObject = new ....)
using (var anotherDisposableObject = new ....)
using (var andAnotherDisposableObject = new ....)
{
} //andAnotherDisposableObject, anotherDisposableObject, otherDisposableObject and connection all disposed
Do bear in mind though that you seem to be mixing garbage collection with disposing an object. In your example, parameters is elegible for garbage collection once execution has exited the using statement as there is no live refence to it.
When it is garbage collected is up to the GC, it might very well never be, depending on your application's memory pressure. If it is garbage collected, then it will be marked as valid for finalization and the finalizer of the object will be scheduled to run. Again, if and when that happens is entirely up to the GC.
Lastly, if the IDisposable pattern of the object is implemented correctly and the finalizer is run, Dispose() will be called (to be precise, Dispose(false) will be called) and the object will dispose any unmanaged resources it might be holding (managed resources can not be disposed safely in this context but it really doesn't matter, the GC will eventually take care of them too).
See IDisposable Pattern for more details on how it works or even better, check out this excellent SO answer.
I have a method that takes FileStream as input. This method is running inside a for loop.
private void UploadFile(FileStream fileStream)
{
var stream = GetFileStream();
// do things with stream
}
I have another method which creates and returns the FileStream:
private FileStream GetFileStream()
{
using(FileStream fileStream = File.Open(myFile, FileMode.Open))
{
//Do something
return fileStream;
}
}
Now the first method throws an ObjectDisposedException when I try to access the returned FileStream, probably because it is already closed since I am using "using" to properly dispose the stream.
If I don't use "using" and instead use it as follows, then the FileStream remains open and the next iteration of the loop (operating on the same file) throws an exception telling the file is already in use:
private FileStream GetFileStream()
{
FileStream fileStream = File.Open(myFile, FileMode.Open);
//Do something
return fileStream;
}
If I use a try-finally block, where I close the stream in the finally then it also throws the ObjectDisposedException.
How to effectively return file stream and close it?
When you return an IDisposable from a method, you are relegating the responsibility of disposing it to your caller. Thus, you need to declare your using block around the entire usage of the stream, which in your case presumably spans the UploadFile call.
using (var s = GetFileStream())
UploadFile(s);
The problem is that the FileStream object is disposed as soon as you exit from the GetFileStream() method, leaving it in an unusable state. As other answers already indicate, you need to remove the using block from that method and instead put the using block around any code that calls this method:
private FileStream GetFileStream()
{
FileStream fileStream = File.Open(myFile, FileMode.Open);
//Do something
return fileStream;
}
using (var stream = GetFileStream())
{
UploadFile(stream);
}
However, I want to take this a step further. You want a way to protect the stream created by your GetFileStream() from the case where a sloppy programmer might call the method without a using block, or at least somehow strongly indicate to callers that the result of this method needs to be enclosed with a using block. Therefore, I recommend this:
public class FileIO : IDisposable
{
private FileStream streamResult = null;
public FileStream CreateFileStream(string myFile)
{
streamResult = File.Open(myFile, FileMode.Open);
//Do something
return streamResult;
}
public void Dispose()
{
if (streamResult != null) streamResult.Dispose();
}
}
using (var io = FileIO())
{
var stream = io.CreateFileStream(myFile);
// loop goes here.
}
Note that you don't necessarily need to create a whole new class for this. You may already have an appropriate class for this method where you can just add the IDisposable code. The main thing is that you can use IDisposable as a signal to other programmers that this code should be wrapped with a using block.
Additionally, this sets you up to modify the class so that you could create your IDisposable object once, before the loop, and have the new class instance keep track of everything you need to dispose at the end of the loop.
If you have a method that need to return an open file stream then all callers of that method need to take responsibility for disposing of the returned stream, since it cannot dispose of the stream before returning it.
I am not sure how to read the code in the question, since the UploadFile method receives fileStream, but then creates its own stream via GetFileStream and does not use fileStream at all.
But still I have a suggestion that might solve similar problems, too.
It called the 'Factory Isolation Pattern' (from the book 'Adaptive Code via C#' by Gary McLean Hall)
The idea is to keep object creation and destruction together, but still allow using the object in a flexible way. And all it takes is a little variation of #frankmartin's original GetFileStream method, only we turn things around and instead of letting the disposable object escape, we let the "do something" in:
private void With(Action<FileStream> do)
{
using (FileStream fileStream = File.Open(myFile, FileMode.Open))
{
do(fileStream);
}
}
You can then use this method in this way:
With(fileStream => UploadFile(fileStream);
Here the user cannot forget to dispose the stream (as #oɔɯǝɹ pointed out), in fact the user does even need know that it has to be disposed or taken care of in any special way ...
Just wanted to verify I will not have any handle leaks and all..
I have the following method
public static MyObject DoSomething(Stream MyStream)
{
var br = new BinaryReader(MyStream);
return DoMoreThings(br);
}
I create MyStream outside..is it safe to say that after this function br will safely be collected by GC? I don't explicitly dispose it..
Although it will be collected by the garbage collector eventually, it's a rather bad practice to leave it there uncollected.
You can ensure that it's cleaned up by wrapping it in a using:
using (var br = new BinaryReader(MyStream))
{
return DoMoreThings(br);
}
The only drawback here is that the using means that it will call br.Dispose, which among other things will close the underlying stream: MyStream in this case. You can prevent that by calling the overloaded constructor, telling it to leave the stream open:
using (var br = new BinaryReader(MyStream, Encoding.UTF8, true))
Replace the Encoding.UTF8 with whatever encoding matches the strings in your file. Encoding.UTF8 is the default used by the constructor that doesn't take an Encoding parameter.
It will be eventually, but you should type it like this instead
using(var br = new BinaryReader(MyStream))
{
return DoMoreThings(br);
}
Using statement is a syntactic sugar on try..finally block, firing Dispose method. All objects implementing IDisposable interface should be disposed manually.
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 .