I often use the "using" block to dispose the objects.
Today, I using HttpWebRequest to post data, and I feel confused between two method.
Method 1:
var request = (HttpWebRequest)WebRequest.Create("http://www...");
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(JsonConvert.SerializeObject(content));
}
Method 2:
var request = (HttpWebRequest)WebRequest.Create("http://www...");
using (var stream = request.GetRequestStream())
using (var writer = new StreamWriter(stream))
{
writer.Write(JsonConvert.SerializeObject(content));
}
In method 2, all stream and streamwirter in "using" blocks, so certainly it will be dispose. But in method 1, I am not sure stream request.GetRequestStream() will be dispose. Can anyone explain to me? Thanks alot!
Basically, it depends on two things:
Whether the StreamWriter constructor will ever throw an exception when passed a non-null Stream reference - and I don't think it will in this case. (If the stream were read-only, it would... at which point the stream wouldn't be disposed.)
Whether StreamWriter.Dispose disposes of the underlying stream - and it does, unless you've called the constructor overload which explicitly allows you to control that
So basically, I believe it's safe in this case... when your using statement disposes of the StreamWriter, that will dispose of the Stream.
As noted in comments, however, using two using statements means you don't need to perform this sort of reasoning.
A StreamWriter wrapping a Stream will close that stream when it is closed. See the docs.
Both are the same. Since using block disposes the entire object, even anonymous objects.
Related
When "nesting" using statements/blocks, such as a StreamWriter within a FileStream
using (FileStream fs = File.Open(path, FileMode.Create))
{
using (var fsw = new StreamWriter(fs))
{
...
}
}
Would the FileStream be properly disposed of if it's reference is implicit? If not, would FileStream dispose of it when it itself is disposed of?
using (var fsw = new StreamWriter(File.Open(path, FileMode.Create)) )
{
...
}
Also, does the following "stacked" using statements generate differently than the first example that is "nested" (are the try/catch blocks nested or not depending on the syntax)?
using (FileStream fs = File.Open(path, FileMode.Create))
using (var fsw = new StreamWriter(fs))
{
...
}
Would the FileStream be properly disposed of if it's reference is implicit? Will FileStream dispose of it when it itself is disposed of?
The question is nonsensical. I believe the question you intended to ask is:
If the StreamWriter (or reader) is disposed (or closed), will it automatically dispose the underlying Stream?
Yes. For future reference, consider reading the documentation; your question is clearly answered there.
Now, you might reason as follows: suppose a thread abort exception is thrown after the creation of the stream but before the creation of the writer or reader. In the two-usings case, the stream is disposed; in the one-using case, it is not. Therefore the two-using case is both different and better.
That reasoning is specious. Suppose a thread abort exception is thrown after the handle for the stream is allocated but before the file stream variable is assigned; even in the two-usings case, the stream is not disposed.
The moral of the story is: you must not rely upon using to dispose of critical resources in a world with thread abort exceptions. using is for politeness; it is not a guarantee that a resource will be deallocated.
does the following "stacked" using statements generate differently than the first example that is "nested"?
Please only ask one question per question.
The question is unclear. Is your question whether the two forms are exactly semantically equivalent, or whether they generate exactly the same IL? Those questions have opposite answer. Yes, they are semantically equivalent, and no, they do not necessarily generate the same IL if optimizations are turned off.
In general,
statement
and
{
statement
}
are semantically equivalent. (Though note that a declaration statement is syntactically illegal in some contexts where a statement block is not. And of course, braces introduce a declaration space.)
However the C# compiler may choose to generate extra nop instructions so that the debugger has some place to put breakpoints associated with the braces. Thus, the code generated is not identical. Generating extra nops can cause knock-on effects on branch locations, and therefore branch offset sizes, and therefore branch instruction sizes, and therefore branch instruction opcodes, for instance.
Would the FileStream be properly disposed of if it's reference made
implicit?
Yes. The var keyword gets determined at compile time and it would result in the same code and be disposed of correctly.
Also, does the following generate differently than the first example
that is nested (are the try/catch blocks nested or not depending on
the syntax)?
There is no catch block with the using statement. The using statement is the equivalent of try finally. Depending on the compiler optimizations, the original code may result in the same as the stacked using statement. Logically, it really shouldn't matter.
Prior to .NET 4.5 the StreamWriter class assumed it owned the stream that was passed into it. So the below will close and dispose of the FileStream when the StreamWriter is closed/disposed.
using (var fsw = new StreamWriter(File.Open(path, FileMode.Create)) )
{
...
}
As of .NET 4.5 there is a StreamWriter constructor with a Boolean parameter that, when True, will leave the FileStream open.
So you have control over whether the FileStream is disposed or not.
As for stacking the using statements: the { }'s are optional when containing a single statement, just as they are for if, for and so on. Stacking the using's is a formatting convenience for those who view the indention to be excessive and unnecessary.
I would suggest following the same convention you would for other block statements when they contain a single statement to keep your code consistent.
I have a readonly FileStream which is a method local variable:
public void SomeMethod()
{
var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
... //some stream operations
}
Should I call Dispose (explicitly or by "using") at the end of the method? What will it change?
It doesn't matter what it does, IDisposable is implemented by FileStream, and so you need to call Dispose implicitly or explicitly when you've finished using it. It is part of the contract of using the class in your code.
I think it's best to wrap that in a using statement. You also need exception handling if you really want that code to be robust. It will work as it is now, it's just bad practice.
It is a must to dispose any instance implementing IDisposable and a good practice to dispose it trough using statement.
Don't think that analyzing every case in particular would help.
If you fail to dispose, the FileStream won't be closed until the GC kicks in (non-deterministically).
And until this happens, you will be holding an open file handle, preventing some types of access to the file (e.g. writing, deletion).
Note that specifying FileShare.ReadWrite won't necessarily help - if another writer attempts to open the file with FileShare.None (e.g. by calling File.OpenWrite), he won't be able to do so until you close the file.
So, yes, do close the file, with a using statement.
If an object can be disposed, you should dispose it as early as you don't need it anymore. From FileStream Class topic:
If a process terminates with part of a file locked or closes a file
that has outstanding locks, the behavior is undefined.
As everyone suggested: dispose every IDisposable, preferably with using.
Now for files there could be special case when you really want to block everyone else from accessing/modifying the file. In this case you'd still dispose file at some point, but this "some point" can be significantly later in the code/application lifetime.
I am redirecting the output of a process into a streamreader which I read later. My problem is I am using multiple threads which SHOULD have separate instances of this stream. When I go to read this stream in, the threading fudges and starts executing oddly. Is there such a thing as making a thread-safe stream? EDIT: I put locks on the ReadToEnd on the streamreader, and the line where I did: reader = proc.StandardOutput;
There's a SyncrhonizedStream built into the framework, they just don't expose the class for you to look at/subclass etc, but you can turn any stream into a SynchronizedStream using
var syncStream = Stream.Synchronized(inStream);
You should pass the syncStream object around to each thread that needs it, and make sure you never try to access inStream elsewhere in code.
The SynchronizedStream just implements a monitor on all read/write operation to ensure that a thread has mutually exclusive access to the stream.
Edit:
Appears they also implements a SynchronizedReader/SynchronizedWriter in the framework too.
var reader = TextReader.Synchronized(process.StandardOutput);
A 'thread-safe' stream doesn't really mean anything. If the stream is somehow shared you must define on what level synchronization/sharing can take place. This in terms of the data packets (messages or records) and their allowed/required ordering.
Am I right that you'd only need a using() for the outermost stream if you're doing e.g
MemoryStream mstr = new MemoryStream();
using(StreamWriter w = new StreamWriter(mstr)) {
....
}
As disposing the StreamWriter should also dispose/close the underlying stream, there's no need to do this ?:
using(MemoryStream mstr = new MemoryStream())
using(StreamWriter w = new StreamWriter(mstr)) {
....
}
(Note these are just examples, for how to dispose wrapped streams, not looking for alternatives like just use a StringWriter etc.)
It's a good idea to put all dependent resources in their own using blocks from a readability and maintainability point of view as much as anything. e.g. in the below code, after the final brace, it's impossible to attempt to access mstr because it is scoped to within the block where it is valid:
using (MemoryStream mstr = new MemoryStream())
using (StreamWriter w = new StreamWriter(mstr) {
....
}
// cannot attempt to access mstr here
If you don't scope it like this, then it's still possible to access mstr outside the scope of where it is valid
MemoryStream mstr = new MemoryStream();
using (StreamWriter w = new StreamWriter(mstr) {
....
}
mstr.Write(...); // KABOOM! ObjectDisposedException occurs here!
So while it may not always be necessary (and in this case it isn't) it's a good idea as it both clarifies and enforces your intention as to its scope.
My rule of thumb: If it implements IDisposable, dispose of it.
While currently (and probably forever), calling StreamWriter.Dispose() closes the underlying stream, other stream-derived classes you may use in the future may not. Also, it seems not to actually call Dispose() either, so non-MemoryStreams may not get properly disposed (although I can't think of any that would suffer from that right now).
So, while you can safely dispose only of the StreamWriter, I find it a much better practice to always use using blocks for disposables whenever possible.
From looking at the StreamWriter.Dispose method in Reflector, it looks like the underlying streams get closed, but not disposed. I would put each stream in a "using" block in order to explicity dispose of them all.
To answer your actual question. TextWriter's Dispose method
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
It calls a protected Dispose and passes true to it. From TextWriter.Dispose Method (Boolean)
When the disposing parameter is true,
this method releases all resources
held by any managed objects that this
TextWriter references. This method
invokes the Dispose method of each
referenced object.
However it is best practice to wrap everything that implements IDisposable in a using block, because we cannot guarantee that that the protected Dipose method will always be called with the true parameter.
It's really a better practice to just always use a using block.
"Always", except for the one well-known case of WCF proxy classes, where a design flaw can sometimes cause their Dispose methods to throw an exception, losing your original exception.
Normally, one writes code something like this to download some data using a WebRequest.
using(WebResponse resp = request.GetResponse()) // WebRequest request...
using(Stream str = resp.GetResponseStream())
; // do something with the stream str
Now if a WebException is thrown, the WebException has a reference to the WebResponse object, which may or may not have Dispose called (depending on where the exception has happened, or how the response class is implemented) - I don't know.
My question is how one is supposed to deal with this. Is one supposed to be coding very defensively, and dispose of the response in the WebException object (that would be a little weird, as WebException is not IDisposable). Or is one supposed to ignore this, potentially accessing a disposed object or never disposing an IDisposable object?
The example given in the MSDN documentation for WebException.Response is wholly inadequate.
I have had a quick peek with Reflector, and can now say:
WebResponse, being an abstract class, delegates all its closing/disposing behaviour to its derived classes.
HttpWebResponse, being the derived class you are almost certainly using here, in its close/dispose methods, is only concerned with disposing the actual response stream. The rest of the class state can be left to the GC's tender mercies.
It follows that it's probably safe to do whatever you like with regard to exception handling, as long as:
When you read the response stream from WebResponse in the try block, enclose it in a using block.
If you read the response stream from WebException in the catch block, enclose it in a using block as well.
There is no need to worry about disposing of WebException itself.
using (var x = GetObject()) {
statements;
}
is (almost) equivalent to
var x = GetObject();
try {
statements;
}
finally {
((IDisposable)x).Dispose();
}
so your object will always be disposed.
This means that in your case
try {
using (WebResponse resp = request.GetResponse()) {
something;
}
}
catch (WebException ex) {
DoSomething(ex.Response);
}
ex.Response will be the same object as your local resp object, which is disposed when you get to the catch handler. This means that DoSomething is using a disposed object, and will likely fail with an ObjectDisposedException.
HttpWebRequest internally makes a memory stream off the underlying network stream before throwing WebException, so there is no unmanaged resource associated with the WebResponse returned from WebException.Response.
This makes it unnecessary to call Dispose() on it. In fact, trying to dispose WebException.Response can cause headache and issues because you may have callers of your code that is attempting to read properties associated with it.
However it is a good practice that you should dispose any IDisposable objects you own. If you decide to do so, make sure you don't have code depending on being able to read WebException.Response properties and/or its stream. The best way would be you handle the exception and throw new type of exception so that you don't leak WebException up to the caller when possible.
And also consider moving to HttpClient which replaces HttpWebRequest.
Disclaimer: No warranty implied.
I'm pretty sure that when you have a using statement the object is disposed, regardless of how you exit the using block (Be it via exception, return or simply progressing through the function).
I suspect you'll find that the object inside the WebException has already been disposed if you let it leave the using block.
Remember, disposing of an object doesn't necessarily prevent accessing it later. It can be unpredictable to try to call methods on it later, causing exceptions of it's own or very weird behavior (And hence I wouldn't recommend it). But even still a large portion of the object is still left behind for the garbage collector even if you dispose it, and hence is still accessible. The purpose of the dispose is typically to clean up resource handles (Like in this case active TCP connections) that for performance reasons you can't realistically leave laying around until the garbage collector finds them. I only mention this to clarify that it's not mutually exclusive for it to be disposed and the exception to hold a reference to it.
A very interesting question (although worth pointing out that the WebResponse object will have been disposed as you exit the using). My gut feeling is that it doesn't really matter that you've got a reference to this disposed WebResponse object as long as you don't try to do anything "operational" with it.
You can probably still access certain properties on the instance for logging purposes (such as the ResponseUri) without getting an ObjectDisposedException, but overall reference held by the exception is not there so you can continue using the instance.
I'd be interested to see what others say.
I get similar cases in EF DB connections.
So i actually create a connections list.
At the end of game , i loop dispose all of them.