Are streams disposed of automatically in a try/catch statement? - c#

If I create a stream inside of the try block and an exception is raised does the stream automatically get disposed of? For example:
try
{
Stream stream = response.GetResponseStream();
//Error Occurs
stream.Close();
}
catch
{
//Handle Error
}
If this is not the way to do it can you please suggest an approach?

No, you need to use finally
Stream stream;
try
{
stream = response.GetResponseStream();
//Error Occurs
}
catch
{
//Handle Error
}
finally
{
if(stream != null)
stream.Close();
}
Or, wrap your Stream declaration/definition in a using statement, which calls Close() automatically:
try
{
using(Stream stream = response.GetResponseStream())
{
//Error happens
}
//stream.Dispose(), which calls stream.Close(), is called by compiler here
}
catch
{
//Handle Error
}
Note that my two examples are not exactly equivalent - in the first, the exception is handled before steam.Close() is called, in the second the exception is handled after.

The stream will not automatically close in this case.
If you wanted to ensure it closes in this context you'll want to use finally to ensure closure.
Alternatively I'd wrap the whole stream in a using.
using(Steam stream = response.GetResponseStream())
{
// Do your work here
}

No, use a using block. It calls Dispose automatically when block finishes, even if an error occurs.
eg.
using (Stream stream = response.GetResponseStream())
{
// do something with stream
}
It's the same as:
Stream stream = null;
try
{
stream = response.GetResponseStream();
// do something with stream
}
finally
{
if (stream != null)
stream.Dispose();
}
There are many examples on the net. A quick Google revealed the following already on stackoverflow: 'using' statement vs 'try finally'

using (Stream stream = response.GetResponseStream())
{
}
Dispose() is called on scope exit. This is the correct idiom for ensuring cleanup of IDisposable objects.

using(resource) statement will take care of calling dispose.

The answer is no. It's best to close all resources in a finally block if you have some exception handling logic around your code.

No, to always ensure disposal, regardless of exceptions, you use:
try
{
Stream stream = response.GetResponseStream();
//Error Occurs
}
catch
{
//Handle Error
}
finally
{
if(stream!=null)
stream.Close();
}
or simply:
using (Stream stream = response.GetResponseStream())
{
}

Stream implements IDisposable interface.
You can use using() statements where the class implements IDisposable.
This will automatically take care of closing and disposing the object without writing finally.
try
{
using (var stream = response.GetResponseStream())
{
//Error happens
}
}
catch
{
//Handle Error
}

Related

Catch exception appropriate when disposing of the result?

Consider the following piece of code:
public static Stream OpenWavStream(string path)
{
var stream = new FileStream(path, FileMode.Open);
try
{
stream.Seek(44, SeekOrigin.Current);
}
catch (Exception)
{
stream.Dispose();
throw;
}
return stream;
}
I'm opening a wav stream whose data always starts at offset 44. If seeking to that offset fails, the stream is disposed, otherwise it is returned. Considering that catch (Exception) is considered bad practice, is it appropriate in this case?
Should one rather research the concrete exceptions (even though the stream should be disposed if any kind of exception happens within the Stream.Seek call) or move it into a finally block?
Only if the Stream fails to load. Something I use:
string fileName = "C:\\PCM.wav";
if (!System.IO.File.Exists(fileName))
{
LogStatus("Wave file not found.");
return;
}
else
{
WaveFileByteArray = File.ReadAllBytes(fileName);
LogStatus("Wave file Loaded!" + Environment.NewLine);
}
This works fine.
then to play/Use:
System.Media.SoundPlayer soundPlayer;
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(WaveFileByteArray, 0, WaveFileByteArray.Length);
soundPlayer.Play();
Relying on an Exception to catch possible errors, like is presented, is not best practice, unless the error is unexpected. Dealing with possible Errors before they occur is best practice.
catch (Exception) is bad practice if you are using it to swallow exceptions and not handling them. You are immediately re-throwing the exception, and doing it properly (you're not doing throw ex; for example). You will need to dispose the stream for any exception, so you should not catch specific exceptions here.
Your code is perfectly fine. However, I am skeptical about the usefulness of the method. Without seeing the rest of the application, it might make sense for the callee to create the stream within a using block, even with a helper method.
//In your callee code
using (var stream = new FileStream(path, FileMode.Open))
{
ConfigureStream(steam);
//Other stuff..
}
public static void ConfigureStream(Stream stream)
{
stream.Seek(44, SeekOrigin.Current);
}
Or, you could check the length of the stream first, to avoid the exception entirely.
Why not use a using block in calling method and leave the closing of steam to the system. using will close the stream even if there is an exception.
public static Stream OpenWavStream(string path)
{
var stream = new FileStream(path, FileMode.Open);
stream.Seek(44, SeekOrigin.Current);
return stream;
}
public static void UseWaveStream()
{
try
{
using(Stream thisStream = OpenWavStream("C:\\myfile.txt"))
{
// do whatever
}
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}

Static Method & Multithreading Issue

I know that static methods aren't always thread safe but if designed properly they are thread safe because internal variables are reinitialized every run...
Below is some code I found here but it looks thread safe because all resources are internalized within the method. Yet it still throws a null pointer sometimes when it tries to release resources (I've commented the line).
public static string XmlHttpRequest(string urlString, string xmlContent)
{
string response = null;
HttpWebRequest httpWebRequest = null;//Declare an HTTP-specific implementation of the WebRequest class.
HttpWebResponse httpWebResponse = null;//Declare an HTTP-specific implementation of the WebResponse class
//Creates an HttpWebRequest for the specified URL.
httpWebRequest = (HttpWebRequest)WebRequest.Create(urlString);
try
{
byte[] bytes;
bytes = System.Text.Encoding.ASCII.GetBytes(xmlContent);
//Set HttpWebRequest properties
httpWebRequest.Method = "POST";
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.ContentType = "text/xml; encoding='utf-8'";
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
//Writes a sequence of bytes to the current stream
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();//Close stream
}
//Sends the HttpWebRequest, and waits for a response.
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
if (httpWebResponse.StatusCode == HttpStatusCode.OK)
{
//Get response stream into StreamReader
using (Stream responseStream = httpWebResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
response = reader.ReadToEnd();
}
}
httpWebResponse.Close();//Close HttpWebResponse
}
catch (WebException we){}
catch (Exception ex) { throw new Exception(ex.Message); }
finally
{
httpWebResponse.Close();
//Here is the null in the line above
httpWebResponse = null;
httpWebRequest = null;
}
return response;
}
So for some reason the line I commented in the code is throwing a null because the httpWebResponse is null. I assume it's something to do with threads using this method. It only happens SOMETIMES.
It has nothing to do with threads. You are likely getting an exception before httpWebResponse is assigned a value. Since you are swallowing any WebException it is entirely possible for httpWebResponse to be null without you knowing that an exception occurred.
Also your other exception handler is throwing a new vanilla exception with just the message included. You lose all other information such as the base exception type and stack trace. You could just rethrow the original exception but that's the same thing as not having another catch block at all.
I would:
remove both catch blocks (or at least the second on)
wrap the httpWebResponse in a using block (then it will be closed automatically if an exception is thrown).
check to see if httpWebResponse before calling Close on it. (note that if you wrap it in a using you don't have to close it, so you don't have to check if it is null)
Also, setting httpWebResponse and httpWebRequest to null is pointless as well since they will be eligible for garbage collection as soon as the method exits.

Serializing data in a backgroundworker - Out of memory exception

I am serializing a class with a binaryformatter and compressing the data with deflatestream. The save function is as follows and is called from a backgroundworker:
public static void save(System system, String filePath)
{
//Make filestream
FileStream fs = new FileStream(filePath, FileMode.Create);
try
{
//Serialize offerte
BinaryFormatter bf = new BinaryFormatter();
DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress);
bf.Serialize(cs, system);
//Push through
fs.Flush();
cs.Flush();
cs.Close();
}
catch (Exception e)
{
var mess = e.Message;
}
finally
{
//Close
fs.Close();
}
}
The class has a number of 'users'. With 100 users it takes 10 seconds and the file is 2MB. With 1000 users it gives an out-of-memory exception (the estimated size is 16MB). Can anyone see a problem here, or give suggestions how to solve this?
(I was first thinking the time on a background thread was causing this, it takes to long. But I have other background threads that can run longer.)
You aren't disposing of your streams, which may be part of the problem, suggest:
public static void save(System system, String filePath)
{
//Make filestream
using(FileStream fs = new FileStream(filePath, FileMode.Create))
{
//Serialize offerte
BinaryFormatter bf = new BinaryFormatter();
using (DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress)) {
bf.Serialize(cs, system);
//Push through
fs.Flush();
cs.Flush();
cs.Close();
}
}
}
This also removes your exception swallowing, which would probably be a good thing.
You use several objects of classes that implement System.IDisposable
If a designer implemented IDisposable he informs you that he might use scarce resources. You might get out of resources before the garbage collector collects the garbage.
In other words: whenever you use a class that implements System.IDisposable you should call Dispose() as soon as you don't need the class anymore. This is especially needed if you need the resources of the class for something else.
You use two Stream classes: FileStream and DeflateStream. They both implement IDisposable. If you don't call Dispose(), the garbage collector eventually will, but in the mean time the resources that these Streams use are not available for anyone else.
The most easy method to make sure that a Disposable object is disposed is by using the using statement:
using (var myStream = new FileStream(...))
{
... // use myStream
}
When the closing bracket is reached, myStream.Dispose() is called, effectively releasing all scarce resources it uses.
This works on every method that is used to leave the {...} block, including break, return, and even Exceptions.
Therefore using is a very safe method: Dispose() will always be called.
By the way: Dispose() will also take care that the Streams are Flushed and Closed, so at the end of the using statement you don't have to Flush() and Close().

Does the FtpWebResponse IDisposable close the response?

I'm using the following code in my program, would I still need to call response.close()? Or does the FtpWebResponse IDisposable implementation close the response?
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
}
So basically, would I need to do this?
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
response.close();
}
No you don't have to call Close, since Dispose already does that. FtpWebResponse is inherited from WebResponse and it has explicitly implemented Dispose, which internally call Close.
Code for WebResponse.cs from : http://www.dotnetframework.org/default.aspx/4#0/4#0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Net/System/Net/WebResponse#cs/1305376/WebResponse#cs
/// <internalonly>
void IDisposable.Dispose() {
try
{
Close();
OnDispose();
}
catch { }
}

Force close a stream

I have an issue from time to time, I have a few StreamReaders and StreamWriters in my program that read info and write it. They go right about 99% of the time, but once in a while I end up with a StreamWriter that won't close, on a piece of code I've run multiple times.
This tends to happen if I spam a function, but I am trying to find a safe way to guarantee a steam disposed. Anyone know how?
try a using statement MSDN
using (StreamWriter stream = new StreamWriter(Initialization)){
//your code
}
this can be useful:
Closing Stream Read and Stream Writer when the form exits
Also you could use a Try Block
try
{
//Declare your streamwriter
StreamWriter sw = new StreamWriter(Initialization);
}
catch
{
//Handle the errors
}
finally
{
sw.Dispose();
}
If the stream's scope is local, always use the following construct:
using (var stream = new Stream())
{
...do stream work here...
}
If on the other hand you are using the stream as a class field then implement the IDisposable pattern and dispose your stream objects when disposing your class: IDisposable
Wrapping the StreamWriter in a using statement is how I usually ensure it is disposed of.
using (var writer = new StreamWriter(#"C:\AFile.txt"))
{
//do some stuff with writer
}
An alternative would be to use a finally block.

Categories