Strange behavior when closing stream

J

John Kraft

Hello all,

I'm experiencing some, imo, strange behavior with the StreamReader
object I am using in the code below. Summary is that I am downloading
a file from a website and saving it to disk for further parsing. I
know, I could use the WebClient and it would be easier, but I don't
have the flexibility I want with it.

This code appears to work exactly the way I want unless the user
cancels the the background operation. In that case, when I call
Close() on the StreamReader object, the method just ends. Nothing
after the call to Close() get executed; which causes some bad side
effect. If I comment out the Reader.Close() line, it work perfectly.
However, I am worried that not closing that stream will cause me
problems somehow.

I have found that it isn't just when I call close, it's when I attempt
to read more data or anything else dealing with the stream. Properties
are ok to check, but methods cause the same behavior.

The code executes correctly if the cancel button is not clicked.

Any ideas or suggestions welcome.

Stats: XP, VS2005, SQLServer 2005

Thanks,

John

p.s. I'm new to .Net2 and threading in general. :)


private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
MyPostVars vasr = e.Argument as MyPostVars;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(vars.ToPostString());

HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("https://www.someCrazyWebsite/Download.do");
request.ContentLength = data.Length;
requ est.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

HttpWebResponse response =
(HttpWebResponse)request.GetResponse();

StreamReader reader = new
StreamReader(response.GetResponseStream());

System.IO.FileInfo file = new
System.IO.FileInfo("outputfile.txt");
if (file.Exists)
{
file.Delete();
}

StreamWriter writer = new StreamWriter(file.FullName);
writer.AutoFlush = true;

int count = 0;
int read = 0;
int size = 65536;
char[] buffer = new char[size];

while (!backgroundWorker.CancellationPending &&
!reader.EndOfStream)
{
count = reader.Read(buffer, 0, size);
read += count;
writer.Write(buffer, 0, count);
backgroundWorker.ReportProgress(0, read);
}

reader.Close(); <-------------------- Problem!!!!!!!!
writer.Close();

if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
}

}
 
S

ssamuel

John,

I don't know too much about the details of your stream -- they tend to
be idiosynchratic -- but try a

using (StreamReader reader = new
StreamReader(response.GetResponseStream()))
{
...
}

block around your reader. You should be able to avoid the call to
Close(), which may solve your problem.

What do you expect to be happening after your Close() call anyway?
Looks like there may be some threading issues. Do you have a try/catch
block around the thread boundary of the background thread?


Stephan




John said:
Hello all,

I'm experiencing some, imo, strange behavior with the StreamReader
object I am using in the code below. Summary is that I am downloading
a file from a website and saving it to disk for further parsing. I
know, I could use the WebClient and it would be easier, but I don't
have the flexibility I want with it.

This code appears to work exactly the way I want unless the user
cancels the the background operation. In that case, when I call
Close() on the StreamReader object, the method just ends. Nothing
after the call to Close() get executed; which causes some bad side
effect. If I comment out the Reader.Close() line, it work perfectly.
However, I am worried that not closing that stream will cause me
problems somehow.

I have found that it isn't just when I call close, it's when I attempt
to read more data or anything else dealing with the stream. Properties
are ok to check, but methods cause the same behavior.

The code executes correctly if the cancel button is not clicked.

Any ideas or suggestions welcome.

Stats: XP, VS2005, SQLServer 2005

Thanks,

John

p.s. I'm new to .Net2 and threading in general. :)


private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
MyPostVars vasr = e.Argument as MyPostVars;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(vars.ToPostString());

HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("https://www.someCrazyWebsite/Download.do");
request.ContentLength = data.Length;
requ est.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

HttpWebResponse response =
(HttpWebResponse)request.GetResponse();

StreamReader reader = new
StreamReader(response.GetResponseStream());

System.IO.FileInfo file = new
System.IO.FileInfo("outputfile.txt");
if (file.Exists)
{
file.Delete();
}

StreamWriter writer = new StreamWriter(file.FullName);
writer.AutoFlush = true;

int count = 0;
int read = 0;
int size = 65536;
char[] buffer = new char[size];

while (!backgroundWorker.CancellationPending &&
!reader.EndOfStream)
{
count = reader.Read(buffer, 0, size);
read += count;
writer.Write(buffer, 0, count);
backgroundWorker.ReportProgress(0, read);
}

reader.Close(); <-------------------- Problem!!!!!!!!
writer.Close();

if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
}

}
 
J

Jon Skeet [C# MVP]

John said:
I'm experiencing some, imo, strange behavior with the StreamReader
object I am using in the code below. Summary is that I am downloading
a file from a website and saving it to disk for further parsing. I
know, I could use the WebClient and it would be easier, but I don't
have the flexibility I want with it.

This code appears to work exactly the way I want unless the user
cancels the the background operation. In that case, when I call
Close() on the StreamReader object, the method just ends. Nothing
after the call to Close() get executed; which causes some bad side
effect.

That sounds like an exception is being thrown.

1) You should work out your general exception handling mechanisms so
that you get to see that exception
2) The exception is likely to provide information which will help you
understand why it's happening.

Jon
 
J

John Kraft

That sounds like an exception is being thrown.

1) You should work out your general exception handling mechanisms so
that you get to see that exception
2) The exception is likely to provide information which will help you
understand why it's happening.

Jon


Thanks for the input, Jon.


I've got a try/catch around the entire inside of the DoWork method,
which from what I've read over the past several days is what you're
supposed to do. No exception "appears" to be thrown; that is, it
never stops inside the catch block. It's as if the thread just ceases
to exist. I've also tried wrapping the individual call to the Close
method inside a try/catch (for troubleshooting purposes) with no
luck. I don't know where else I could put a try/catch to catch such
an exception.

The part that really "creeps" me out is that it only seems to occur if
I try to act on the streamreader. If I comment out the call, the
function terminates normally.
 
J

John Kraft

John,

I don't know too much about the details of your stream -- they tend to
be idiosynchratic -- but try a

using (StreamReader reader = new
StreamReader(response.GetResponseStream()))
{
...
}

block around your reader. You should be able to avoid the call to
Close(), which may solve your problem.

What do you expect to be happening after your Close() call anyway?
Looks like there may be some threading issues. Do you have a try/catch
block around the thread boundary of the background thread?


Stephan

Thanks for the reply, Stephan.

I just tried that possibility. What I discovered is that when the
compiler gets to the closing brase of the using statement, the method
terminates exactly the way it did with the Close method.

What I expect to happen, is for the method to complete execution. Out
of habit, I always close my readers before i close my writers. In
this case, the premature exiting of the method causes the
writer.Close() and subsequent instructions to not execute. The has
the side effect of keeping the output file "locked" until I exit the
application. This causes me to be unable to perform the necessary
parsing of the files at a later point in the application.

Aside from those effects, I don't want to be hogging up system
resources anywhere by having an open stream to a server on the
internet; especially if users decide to cancel the download and
restart it at a later time.

Thanks,

John
 
S

ssamuel

John,

First, in this case, you probably should be closing the writer before
the reader. Based on what your code looks like, you're using the writer
to re-write what came in from the reader; therefore, the writer depends
on the reader and should always be closed first. If your "always reader
before writer" philosophy came from a rule of thumb, you should
consider that this may be one of (possibly few) times when it doesn't
apply.

Second, what's going on in the background thread? Are you manipulating
the same streams or otherwise related objects? Are you catching
exceptions at the boundaries of that thread? Very often, when things go
silently into the night, it's because you're throwing exceptions in
background threads. There's no exception handling on them and they're
not in the process foreground so you'll rarely hear from them when they
crash.

Stephan
 
J

John Kraft

John,

First, in this case, you probably should be closing the writer before
the reader. Based on what your code looks like, you're using the writer
to re-write what came in from the reader; therefore, the writer depends
on the reader and should always be closed first. If your "always reader
before writer" philosophy came from a rule of thumb, you should
consider that this may be one of (possibly few) times when it doesn't
apply.

Second, what's going on in the background thread? Are you manipulating
the same streams or otherwise related objects? Are you catching
exceptions at the boundaries of that thread? Very often, when things go
silently into the night, it's because you're throwing exceptions in
background threads. There's no exception handling on them and they're
not in the process foreground so you'll rarely hear from them when they
crash.

Stephan

Stephan,

The reader first thing was just something I've always done. No real
"logic" behind it. I think I just always do that because it helps me
to remember too. But, your reasoning makes plenty o' sense. However,
with the using statement, I am closing the writer first with no change
in the wierd behavior.

As for the threading, the DoWork method IS the background thread.
According to the threading books I've been reading, it is a
recommended practice to put a try as the first line of the DoWork
method and wrap all execution inside the try/catch. Nothing is being
caught inside that catch block, but I realize that doesn't mean it's
not being thrown somewhere deeper.

As for manipulation of the streams, all of it takes place inside that
one thread. They are created, used, and destroyed in that one method;
which is running in it's own thread.

Thanks,

John
 
C

Christof Nordiek

Hi John,

is it possible, that the MessageBox.Show throws an exception?
This would explain, why the exception is lost totally. Maybe there is a
problem with MessageBox.Show in a Background-thread.
Did you step through the application in the debugger? Then it stopp at least
at the Show statement (if my assumption is true.)

John Kraft said:
Hello all,

I'm experiencing some, imo, strange behavior with the StreamReader
object I am using in the code below. Summary is that I am downloading
a file from a website and saving it to disk for further parsing. I
know, I could use the WebClient and it would be easier, but I don't
have the flexibility I want with it.

This code appears to work exactly the way I want unless the user
cancels the the background operation. In that case, when I call
Close() on the StreamReader object, the method just ends. Nothing
after the call to Close() get executed; which causes some bad side
effect. If I comment out the Reader.Close() line, it work perfectly.
However, I am worried that not closing that stream will cause me
problems somehow.

I have found that it isn't just when I call close, it's when I attempt
to read more data or anything else dealing with the stream. Properties
are ok to check, but methods cause the same behavior.

The code executes correctly if the cancel button is not clicked.

Any ideas or suggestions welcome.

Stats: XP, VS2005, SQLServer 2005

Thanks,

John

p.s. I'm new to .Net2 and threading in general. :)


private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
MyPostVars vasr = e.Argument as MyPostVars;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(vars.ToPostString());

HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("https://www.someCrazyWebsite/Download.do");
request.ContentLength = data.Length;
requ est.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();

HttpWebResponse response =
(HttpWebResponse)request.GetResponse();

StreamReader reader = new
StreamReader(response.GetResponseStream());

System.IO.FileInfo file = new
System.IO.FileInfo("outputfile.txt");
if (file.Exists)
{
file.Delete();
}

StreamWriter writer = new StreamWriter(file.FullName);
writer.AutoFlush = true;

int count = 0;
int read = 0;
int size = 65536;
char[] buffer = new char[size];

while (!backgroundWorker.CancellationPending &&
!reader.EndOfStream)
{
count = reader.Read(buffer, 0, size);
read += count;
writer.Write(buffer, 0, count);
backgroundWorker.ReportProgress(0, read);
}

reader.Close(); <-------------------- Problem!!!!!!!!
writer.Close();

if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
}

}
 
J

Jon Skeet [C# MVP]

John Kraft said:
I've got a try/catch around the entire inside of the DoWork method,
which from what I've read over the past several days is what you're
supposed to do. No exception "appears" to be thrown; that is, it
never stops inside the catch block. It's as if the thread just ceases
to exist. I've also tried wrapping the individual call to the Close
method inside a try/catch (for troubleshooting purposes) with no
luck. I don't know where else I could put a try/catch to catch such
an exception.

The part that really "creeps" me out is that it only seems to occur if
I try to act on the streamreader. If I comment out the call, the
function terminates normally.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
J

John Kraft

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.


Jon,

I appreciate all the help. I'll see if I can come up with something.
The reason I didn't already post the complete code is that the
information that I'm sending is sensitive information that is posting
against a U.S. government website. Even if I were to give you the
entire program, you wouldn't be able to perform the download without
the post data; which I'm not at liberty to give out. I think maybe
this week/weekend I'll see if I can reproduce the issue downloading a
file against some other website or even just a simple filestream. If
I can, then I'll post the program with that code.

Thanks again,

John
 
J

John Kraft

Hi John,

is it possible, that the MessageBox.Show throws an exception?
This would explain, why the exception is lost totally. Maybe there is a
problem with MessageBox.Show in a Background-thread.
Did you step through the application in the debugger? Then it stopp at least
at the Show statement (if my assumption is true.)

Christof,

That's funny, I didn't even realize I left that MessageBox in there
when I posted the sample. That's why I had it there, I just needed a
line of code for the debugger to stop on. The debugger never even
reaches the line of code. It never enters the catch block.

Thanks though,

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top