If I have a using block, where I create an object (e.g. a FileStream object), and that object fails to create (returns null, throws an exception, etc.), does the code in the block still execute?
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
// do stuff with fs here
}
// do more stuff after
If the FileStream constructor were to return null (if the FileStream constructor always returns a valid object, let's just say for sake of argument that it is possible to return null), would the code inside execute? Or would it skip over the "do stuff with fs here" code?
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
// do stuff with fs here
}
// do more stuff after
is equivalent to:
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
try
{
// do stuff with fs here
}
finally
{
if (fs != null)
{
((IDisposable)fs).Dispose();
}
}
// do more stuff after
So to answer your question:
If the FileStream constructor were to return null (if the FileStream
constructor always returns a valid object, let's just say for sake of
argument that it is possible to return null), would the code inside
execute?
Yes, it will.
Obviously everyone familiar with the C# specification knows that a constructor (no matter for which type) can never return null which kind of makes your question a bit unrealistic.
The exception would get handled as usual i.e. by the enclosing try...catch if you have one or by the system.
If it throws an exception, it's definitely not going to execute. If no exception is thrown, it's going to try and execute the block. Though if it were to return null, my guess is it wouldn't get far before throwing an exception from inside and quitting.
The code will execute regardless of that so you'll need to protect your code against it. Take for example this console application, the WriteLine will execute.
class Program
{
static void Main(string[] args)
{
using (null)
{
Console.WriteLine("Hello.");
}
}
}
Related
Is the compiler able to merge any of the following code into a single try/catch?
using (FileStream stream = new FileStream(filePath, FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(stream))
{
a try/catch around my actual code...
}
}
If not, would there be any functional difference if I do this instead?
FileStream stream = null;
BinaryReader reader = null;
try
{
stream = new FileStream(filePath, FileMode.Open);
reader = new BinaryReader(stream)
// do my stuff
}
catch (stuff)
{
}
finally
{
if (stream != null)
stream.Close();
if (reader != null)
reader.Close();
}
Since the overhead of having an extra try/finally is virtually zero, there is no difference if the compiler combines two blocks in one or keeps them separate. Your translated code would have a single try-catch embedded inside two layers of try-finally, which are virtually free in terms of performance.
Converting the using code manually has a different implication - the visibility of variables is different. Your translation of nested using statements leaves stream and reader variables accessible after the block. They refer to a closed stream and a closed reader. Regular using, on the other hand, keeps its variables inside its scope, as if an additional pair of curly braces were placed around the whole block:
{ // <<==
FileStream stream = null;
BinaryReader reader = null;
try {
stream = new FileStream(filePath, FileMode.Open);
reader = new BinaryReader(stream)
// do my stuff
} finally {
if (stream != null)
stream.Close();
if (reader != null)
reader.Close();
}
} // <<==
using is better in this way, because it lets you avoid an extra level of nesting while keeping its variable in local scope. Moreover, you could reduce the level of nesting in your source by placing two consecutive using blocks together at the same level of indentation, with no curly braces:
using (FileStream stream = new FileStream(filePath, FileMode.Open))
using (BinaryReader reader = new BinaryReader(stream)) {
a try/catch around my actual code...
}
Is the compiler able to merge any of the following code into a single try/catch?
No, the compiler is not able to make your code behave differently from what you've written. And it would be different even without the possibility of Close() and Dispose() having different effects, but let's pretend you called Dispose() yourself.
If not, would there be any functional difference if I do this instead?
Yes. Putting both Dispose() invocations in a single finally block means that reader won't be disposed if stream.Dispose() throws an exception.
No well-written IDisposable's Dispose() method throws an exception, but the compiler cannot know or assume that all implementations are well-written.
The new Visual Studio 2012 is complaining about a common code combination I have always used. I know it seems like overkill but I have done the following in my code 'just to be sure'.
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
// Code here
}
}
Visual studio is 'warning' me that I am disposing of fs more than once. So my question is this, would the proper way to write this be:
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var sr = new StreamReader(fs);
// do stuff here
}
Or should I do it this way (or some other variant not mentioned).
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var sr = new StreamReader(fs))
{
// Code here
}
I searched several questions in StackOverflow but did not find something that addressed the best practice for this combination directly.
Thank you!
The following is how Microsoft recommends doing it. It is long and bulky, but safe:
FileStream fs = null;
try
{
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (TextReader tr= new StreamReader(fs))
{
fs = null;
// Code here
}
}
finally
{
if (fs != null)
fs.Dispose();
}
This method will always ensure that everything is disposed that should be despite what exceptions may be thrown. For example, if the StreamReader constructor throws an exception, the FileStream would still be properly disposed.
Visual studio is 'warning' me that I am disposing of fs more than once.
You are, but that is fine. The documentation for IDisposable.Dispose reads:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times.
Based on that, the warning is bogus, and my choice would be to leave the code as it is, and suppress the warning.
As Dan's answer only appears to work with StreamWriter, I believe this might be the most acceptable answer.
(Dan's answer will still give the disposed twice warning with StreamReader - as Daniel Hilgarth and exacerbatedexpert mentions, StreamReader disposes the filestream)
using (TextReader tr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
string line;
while ((line = tr.ReadLine()) != null)
{
// Do work here
}
}
This is very similar to Daniel Hilgarth's answer, modified to call dispose via the Using statement on StreamReader as it is now clear StreamReader will call dispose on FileStream (According to all the other posts, documentation referenced)
Update:
I found this post. For what it is worth.
Does disposing streamreader close the stream?
Yes, the correct way would be to use your first alternative:
using (FileStream fs = new FileStream(filePath, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite))
{
TextReader tr = new StreamReader(fs);
// do stuff here
}
The reason is the following:
Disposing the StreamReader only disposes the FileStream so that's actually the only thing you need to dispose.
Your second option (just the inner "using") is no solution as it would leave the FileStream undisposed if there was an exception inside the constructor of the StreamReader.
It's because the way you used StreamReader disposes the stream when it is disposed. So, if you dispose the stream too, it's being disposed twice. Some consider this a flaw in StreamReader--but it's there none-the-less. In VS 2012 (.NET 4.5) there is an option in StreamReader to not dispose of the stream, with a new constructor: http://msdn.microsoft.com/en-us/library/gg712952
Two solutions:
A) You trust Reflector or Documentation and you know *Reader and *Writer will close the underlying *Stream. But warning: it won't work in case of a thrown Exception. So it is not the recommended way:
using (TextReader tr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
// Code here
}
B) You ignore the warning as documentation states The object must not throw an exception if its Dispose method is called multiple times. It's the recommended way, as it's both a good practice to always use using, and safe in case of a thrown Exception:
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
internal void myMethod()
{
[...]
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (TextReader tr = new StreamReader(fs))
{
// Code here
}
}
Given all the nonsense this (perfectly legitimate!) question generated, this would be my preference:
FileStream fs = null;
TextReader tr= null;
try
{
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
tr= new StreamReader(fs);
// Code here
}
finally
{
if (tr != null)
tr.Dispose();
if (fs != null)
fs.Dispose();
}
The links below illustrate perfectly legal syntax. IMO, this "using" syntax is far preferable to nested "using". But I admit - it does not solve the original question:
http://blogs.msdn.com/b/ericgu/archive/2004/08/05/209267.aspx
.NET - Replacing nested using statements with single using statement
IMHO...
On this code:
public static string Base64FromFileName(string fileName)
{
try
{
FileInfo fInfo = new FileInfo(fileName);
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
byte[] bdata = br.ReadBytes((int)numBytes);
br.Close();
fStream.Close();
return Convert.ToBase64String(bdata);
}
catch(Exception e)
{
throw e;
}
}
...I get, courtesy of Visual Studio's Code Analysis tool, the warning, "Do not dispose objects multiple times...To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object" on the "fStream.Close();" line.
Why? Is fStream disposed in the line above, where the BinaryReader is closed?
Wouldn't I be better off refactoring it like this anyway:
. . .
using (FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fStream))
{
byte[] bdata = br.ReadBytes((int)numBytes);
} //br.Close();
} //fStream.Close();
. . .
?
BinaryReader.Close also closes the underlying stream, so this would indeed cause the stream to be disposed of twice. But that's not a real problem, disposing twice doesn't hurt.
You could write this much better as
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
using (var br = new BinaryReader(fs, new UTF8Encoding(), true))
{
return Convert.ToBase64String(br.ReadBytes((int)numBytes));
}
This is the bomb-proof version:
Anything that is successfully constructed is guaranteed to be disposed
You won't dispose of the stream twice because the boolean leaveOpen argument on the BinaryReader constructor ensures that disposing (closing) it won't also close the stream
Code Analysis is right; Code Analysis is wrong.
Yes, you're closing the FileStream twice. This is harmless. So is disposing it twice. Multiple disposal happens. It is the responsibility of the developer of a disposable component to handle multiple disposal properly and without throwing exceptions1.
However, while calling Dispose() on a disposed FileStream is a no-op by convention, the same isn't true of your code, which calls Close() on a disposed stream. Don't do that.
Your suggested fix with the nested using is fine.
1 The contract for IDisposable.Dispose requires:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
The formal term for this behavior is idempotence.
Should I be using the using keyword or a dispose method with the following code (since I am opening a stream):
class Program
{
static void Main(string[] args)
{
var x = Deserialize<Dog>(new FileStream(#"C:\Documents and Settings\name\Desktop\demo.xml", FileMode.Open));
}
static T Deserialize<T>(Stream s)
{
XmlSerializer ser = new XmlSerializer(typeof(T));
return (T)ser.Deserialize(s);
}
}
If not, can you please explain why not (does a new FileStream automatically dispose/close the stream)?
You should be using using:
using(var stream = new FileStream(#"C:\path\demo.xml", FileMode.Open))
{
var x = Deserialize<Dog>(stream);
// more code ...
}
Yes you should dispose the stream. If you were to use the File.ReadAllText() for example, this static method would open a stream and dispose it for you. I would suggest a Using, this is because it'll handle exceptions too. For example in this noddy example:
This version correctly disposes the FileStream:
using(FileStream fs = FileStream(path, FileMode.Open))
{
throw new Exception();
}
This example leaks the resources used by the FileStream, you could add try/catch blocks but then it's less readable.
FileStream fs = new FileStream(path, FileMode.Open);
throw new Exception();
fs.Dispose();
If you use using block , he execute in the end of treatment Dispose method.
You use using, because FileStream is non managed object, so Garbage collector don't have informatiosn abouts this object in order to clean, so the developper must clean ressource in order to help your GC.
Link : http://msdn.microsoft.com/fr-fr/library/yh598w02(v=vs.80).aspx
you should use Using with everything that implements IDisposable :)
As already mentioned, you should use using. But why? Well, as already mentioned you should use using for all objects that implements IDisposable.
In your case, FileStream inherits from the Stream object which is implementing IDisposable. Read more about FileStream here: msdn
The new Visual Studio 2012 is complaining about a common code combination I have always used. I know it seems like overkill but I have done the following in my code 'just to be sure'.
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
// Code here
}
}
Visual studio is 'warning' me that I am disposing of fs more than once. So my question is this, would the proper way to write this be:
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var sr = new StreamReader(fs);
// do stuff here
}
Or should I do it this way (or some other variant not mentioned).
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var sr = new StreamReader(fs))
{
// Code here
}
I searched several questions in StackOverflow but did not find something that addressed the best practice for this combination directly.
Thank you!
The following is how Microsoft recommends doing it. It is long and bulky, but safe:
FileStream fs = null;
try
{
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (TextReader tr= new StreamReader(fs))
{
fs = null;
// Code here
}
}
finally
{
if (fs != null)
fs.Dispose();
}
This method will always ensure that everything is disposed that should be despite what exceptions may be thrown. For example, if the StreamReader constructor throws an exception, the FileStream would still be properly disposed.
Visual studio is 'warning' me that I am disposing of fs more than once.
You are, but that is fine. The documentation for IDisposable.Dispose reads:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times.
Based on that, the warning is bogus, and my choice would be to leave the code as it is, and suppress the warning.
As Dan's answer only appears to work with StreamWriter, I believe this might be the most acceptable answer.
(Dan's answer will still give the disposed twice warning with StreamReader - as Daniel Hilgarth and exacerbatedexpert mentions, StreamReader disposes the filestream)
using (TextReader tr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
string line;
while ((line = tr.ReadLine()) != null)
{
// Do work here
}
}
This is very similar to Daniel Hilgarth's answer, modified to call dispose via the Using statement on StreamReader as it is now clear StreamReader will call dispose on FileStream (According to all the other posts, documentation referenced)
Update:
I found this post. For what it is worth.
Does disposing streamreader close the stream?
Yes, the correct way would be to use your first alternative:
using (FileStream fs = new FileStream(filePath, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite))
{
TextReader tr = new StreamReader(fs);
// do stuff here
}
The reason is the following:
Disposing the StreamReader only disposes the FileStream so that's actually the only thing you need to dispose.
Your second option (just the inner "using") is no solution as it would leave the FileStream undisposed if there was an exception inside the constructor of the StreamReader.
It's because the way you used StreamReader disposes the stream when it is disposed. So, if you dispose the stream too, it's being disposed twice. Some consider this a flaw in StreamReader--but it's there none-the-less. In VS 2012 (.NET 4.5) there is an option in StreamReader to not dispose of the stream, with a new constructor: http://msdn.microsoft.com/en-us/library/gg712952
Two solutions:
A) You trust Reflector or Documentation and you know *Reader and *Writer will close the underlying *Stream. But warning: it won't work in case of a thrown Exception. So it is not the recommended way:
using (TextReader tr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
// Code here
}
B) You ignore the warning as documentation states The object must not throw an exception if its Dispose method is called multiple times. It's the recommended way, as it's both a good practice to always use using, and safe in case of a thrown Exception:
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
internal void myMethod()
{
[...]
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (TextReader tr = new StreamReader(fs))
{
// Code here
}
}
Given all the nonsense this (perfectly legitimate!) question generated, this would be my preference:
FileStream fs = null;
TextReader tr= null;
try
{
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
tr= new StreamReader(fs);
// Code here
}
finally
{
if (tr != null)
tr.Dispose();
if (fs != null)
fs.Dispose();
}
The links below illustrate perfectly legal syntax. IMO, this "using" syntax is far preferable to nested "using". But I admit - it does not solve the original question:
http://blogs.msdn.com/b/ericgu/archive/2004/08/05/209267.aspx
.NET - Replacing nested using statements with single using statement
IMHO...