Force close a stream - c#

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.

Related

Why do these two StreamWriter constructors give me different results?

Long story short I am trying to send a string via TcpClient using StreamWriter.
Without changing any other code except swapping out these samples. They produce different results.
In code sample 1 the StreamReader picks up that it has DataAvailable and the message is received.
In code sample 2 it does not have DataAvailable so no message is received. I need to keep my underlying stream open hence needing to use the constructor of StreamWrite in sample 2.
Sample 1 - Write Method
public void SendMessage(string message)
{
message = "TestMessage";
//WORKING - Sample 1
using (var sw = new StreamWriter(stream))
{
sw.Write(message);
sw.Flush();
}
}
Sample 2 - Write Method
public void SendMessage(string message)
{
message = "TestMessage";
//NOT WORKING - Sample 2
var encoding = new UTF8Encoding(false, true);
using (var sw = new StreamWriter(stream, encoding, 1024, true))
{
sw.Write(message);
sw.Flush();
}
}
Read Method
public string ReadMessage()
{
if (!stream.DataAvailable)
return null;
//I have also tried
//if(sr.Peek() == 0)
// return null;
string message = sr.ReadToEnd();
return message;
}
NOTE: If I put both samples together with the working one last I get the message received "TestMessageTestMessage" so it is definitely writing to stream however it is not setting DataAvailable to true?
Any Idea's why?
The problem is your ReadToEnd() command which blocks indefinitely on a NetworkStream which has no end until closed. I tested your code and I went past the DataAvailable query and blocked on the ReadToEnd() command.
Your method that uses a constructor that allows the BaseStream to stay open means that you never have an end to your stream. When the working method closes the stream the ReadMessage method returns with everything in the stream.
The solution: Do not attempt to read to the end. Read in blocks while the data is available or introduce a terminating character and read to that character.
From MSDN:
ReadToEnd assumes that the stream knows when it has reached an end. For interactive protocols in which the server sends data only when you ask for it and does not close the connection, ReadToEnd might block indefinitely because it does not reach an end, and should be avoided.

Overwrite instance of BinaryWriter C#

I have a class that needs to keep an instance of a BinaryWriter open over several write function calls (data is packet based). It also has to create a new file once it has written a certain amount of data/packets.
Normally I would just close the Binary Writer and reinstantiate it with a new file path, but the overhead associated with that operation is too great for my application. I tried closing the writer in a seperate thread, but that interferes with the new instance I create later.
My last ditch attempt was not to close the Writer (and stream) at all, and simply create a new instance of it everytime I'd written the required packets. This seems to work, and doesn't cause any memory leaks, but I'd really like to know what goes on if you do this.
Here is my (simplified) code to illustrate:
class Writer
{
BinaryWriter binWriter;
int bytesWritten;
int filesWritten;
const int maxFilesize = 10E9;
Writer(string filepath)
{
binWriter = new BinaryWriter(File.Open(filepath, FileMode.Create));
bytesWritten = 0;
filesWritten = 0;
}
WritePacket(byte[] packet)
{
if(bytesWritten<maxFileSize)
{
binWriter.Write(packet);
bytesWritten += packet.Length;
}
else
{
// this is where I'd normally call Dispose(), but the overhead
// is too high, and disposing the stream in a seperate thread
// interferes with the new one
// what actually happens here? it's the only thing I've found to
//work...
filesWritten++;
binWriter = new BinaryWriter(File.Open(filepath + filesWritten, FileMode.Create));
}
}
It feels bad, but this is the only solution that works so far. Any insight would be great!

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());
}
}

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().

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

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
}

Categories