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.
Related
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
}
Code snippet is as follows
public static string ToCompressedBase64(this string text)
{
using (var memoryStream = new MemoryStream())
{
using (var gZipOutputStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
using (var streamWriter = new StreamWriter(gZipOutputStream))
{
streamWriter.Write(text);
}
}
return Convert.ToBase64String(memoryStream.ToArray());
}
}
As far as I know, if class contains field which is IDisposable then It should implement IDisposable itself and take care of disposal of the owned object, so with this assumptions, after disposal of streamWriter the gZipOutputStream and memoryStream will also be disposed. But we still need not disposed memoryStream to invoke toArray() method on It.
So the question is, Is calling ToArray() method on memoryStream at the end safe?
If I understand your question correctly, you are asking if it's safe to call ToArray() on a MemoryStream after it has been disposed.
If so, then yes, it's safe. The documentation specifies:
This method works when the MemoryStream is closed.
EDIT: And in case it's not clear whether closed also means disposed, you can also look at the source code for the Dispose method (Note: The link is to Stream.Dispose() since MemoryStream doesn't override the Dispose method):
public void Dispose()
{
/* These are correct, but we'd have to fix PipeStream & NetworkStream very carefully.
Contract.Ensures(CanRead == false);
Contract.Ensures(CanWrite == false);
Contract.Ensures(CanSeek == false);
*/
Close();
}
As you can see, calling Dispose() does nothing more than calling Close().
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 ...
Classes such as Stream, StreamReader, StreamWriter etc implements IDisposable interface. That means, we can call Dispose() method on objects of these classes. They've also defined a public method called Close(). Now that confuses me, as to what should I call once I'm done with objects? What if I call both?
My current code is this:
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
writer.Close();
}
reader.Close();
}
}
As you see, I've written using() constructs, which automatically call Dispose() method on each object. But I also call Close() methods. Is it right?
Please suggest me the best practices when using stream objects. :-)
MSDN example doesn't use using() constructs, and call Close() method:
How to: Download Files with FTP
Is it good?
A quick jump into Reflector.NET shows that the Close() method on StreamWriter is:
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
And StreamReader is:
public override void Close()
{
this.Dispose(true);
}
The Dispose(bool disposing) override in StreamReader is:
protected override void Dispose(bool disposing)
{
try
{
if ((this.Closable && disposing) && (this.stream != null))
{
this.stream.Close();
}
}
finally
{
if (this.Closable && (this.stream != null))
{
this.stream = null;
/* deleted for brevity */
base.Dispose(disposing);
}
}
}
The StreamWriter method is similar.
So, reading the code it is clear that that you can call Close() & Dispose() on streams as often as you like and in any order. It won't change the behaviour in any way.
So it comes down to whether or not it is more readable to use Dispose(), Close() and/or using ( ... ) { ... }.
My personal preference is that using ( ... ) { ... } should always be used when possible as it helps you to "not run with scissors".
But, while this helps correctness, it does reduce readability. In C# we already have plethora of closing curly braces so how do we know which one actually performs the close on the stream?
So I think it is best to do this:
using (var stream = ...)
{
/* code */
stream.Close();
}
It doesn't affect the behaviour of the code, but it does aid readability.
No, you shouldn't call those methods manually. At the end of the using block the Dispose() method is automatically called which will take care to free unmanaged resources (at least for standard .NET BCL classes such as streams, readers/writers, ...). So you could also write your code like this:
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
}
The Close() method calls Dispose().
The documentation says that these two methods are equivalent:
StreamReader.Close: This implementation of Close calls the Dispose method passing a true value.
StreamWriter.Close:
This implementation of Close calls the Dispose method passing a true value.
Stream.Close: This method calls Dispose, specifying true to release all resources.
So, both of these are equally valid:
/* Option 1, implicitly calling Dispose */
using (StreamWriter writer = new StreamWriter(filename)) {
// do something
}
/* Option 2, explicitly calling Close */
StreamWriter writer = new StreamWriter(filename)
try {
// do something
}
finally {
writer.Close();
}
Personally, I would stick with the first option, since it contains less "noise".
For what it's worth, the source code for Stream.Close explains why there are two methods:
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup now.
In short, Close is only there because it predates Dispose, and it can't be deleted for compatibility reasons.
This is an old question, but you can now(C# 8.0) write using statements without needing to block each one. They will be disposed of in reverse order when the containing block is finished.
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream);
using var writer = new StreamWriter(filename);
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using
On many classes which support both Close() and Dispose() methods, the two calls would be equivalent. On some classes, however, it is possible to re-open an object which has been closed. Some such classes may keep some resources alive after a Close, in order to permit reopening; others may not keep any resources alive on Close(), but might set a flag on Dispose() to explicitly forbid re-opening.
The contract for IDisposable.Dispose explicitly requires that calling it on an object which will never be used again will be at worst harmless, so I would recommend calling either IDisposable.Dispose or a method called Dispose() on every IDisposable object, whether or not one also calls Close().
Just to complement other answers, as of C# 8.0, you don't need to open a block of code just to use an using statement
if (...)
{
using FileStream f = new FileStream(#"C:\users\jaredpar\using.md");
// statements
}
// Equivalent to
if (...)
{
using (FileStream f = new FileStream(#"C:\users\jaredpar\using.md"))
{
// statements
}
}
docs:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using