Why is this code causing errors saying the file is in use by another process?

M

Mike Cain

I'm writing a Windows service using C# (VS.NET 2005, .NET framework 2.0)
that downloads a binary file from the web once every 15 minutes.The first
time it downloads the file it works great. However for some reason it is not
closing/releasing the file completely. So in subsequent attempts my code
throws an IO exception saying that it cannot overwrite my target file
"because it is being used by another process".I know the immediate answer
that comes to mind is that I must not be properly closing the steams.
However I am quite certain I am doing this!!At first I just had this
code:WebClient request = new WebClient();request.Credentials = new
NetworkCredential("anonymous",
"nothing");try{request.DownloadFile(serverUri,
filePathAndNameToStoreDownloadedFile);}catch (WebException
e){Log.Error("Unexepected error trying to download update: " +
e.ToString());success = false;}finally {request.Dispose()}That looked pretty
solid so I started thinking that this must be a bug within the .NET
framework.So then I found a C# function on the web (enclosed below) that
looked well written and properly closes everything.However I was SHOCKED to
find that I ran into the SAME EXACT PROBLEM. The first time the service
starts up it works fine. But on all subsequent attempts I get this error
about the file being in use.Everything appears to be in order. What am I
missing here?? This is driving me nuts so any help is greatly
appreciated!!Thanks!![for reference here's the code I found on the net which
exhibits the same issue I get when using the simplier .DownloadFile method
on the WebClient object.]public static int DownloadFile(String
remoteFilename,
String localFilename)
{
// Function will return the number of bytes processed
// to the caller. Initialize to 0 here.
int bytesProcessed = 0;

// Assign values to these objects here so that they can
// be referenced in the finally block
Stream remoteStream = null;
Stream localStream = null;
WebResponse response = null;

// Use a try/catch/finally block as both the WebRequest and Stream
// classes throw exceptions upon error
try
{
// Create a request for the specified remote file name
WebRequest request = WebRequest.Create(remoteFilename);
if (request != null)
{
// Send the request to the server and retrieve the
// WebResponse object
response = request.GetResponse();
if (response != null)
{
// Once the WebResponse object has been retrieved,
// get the stream object associated with the response's data
remoteStream = response.GetResponseStream();

// Create the local file
localStream = File.Create(localFilename);

// Allocate a 1k buffer
byte[] buffer = new byte[1024];
int bytesRead;

// Simple do/while loop to read from stream until
// no bytes are returned
do
{
// Read data (up to 1k) from the stream
bytesRead = remoteStream.Read (buffer, 0, buffer.Length);

// Write the data to the local file
localStream.Write (buffer, 0, bytesRead);

// Increment total bytes processed
bytesProcessed += bytesRead;
} while (bytesRead > 0);
}
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Close the response and streams objects here
// to make sure they're closed even if an exception
// is thrown at some point
if (response != null) response.Close();
if (remoteStream != null) remoteStream.Close();
if (localStream != null) localStream.Close();
}

// Return total bytes processed to caller.
return bytesProcessed;
}
 
L

leon.friesema

Mike Cain said:
I'm writing a Windows service using C# (VS.NET 2005, .NET framework 2.0)
that downloads a binary file from the web once every 15 minutes.The first
time it downloads the file it works great. However for some reason it is not
closing/releasing the file completely. So in subsequent attempts my code
throws an IO exception saying that it cannot overwrite my target file
"because it is being used by another process".I know the immediate answer
that comes to mind is that I must not be properly closing the steams.
However I am quite certain I am doing this!!At first I just had this
code:WebClient request = new WebClient();request.Credentials = new
NetworkCredential("anonymous",
"nothing");try{request.DownloadFile(serverUri,
filePathAndNameToStoreDownloadedFile);}catch (WebException
e){Log.Error("Unexepected error trying to download update: " +
e.ToString());success = false;}finally {request.Dispose()}That looked pretty
solid so I started thinking that this must be a bug within the .NET
framework.So then I found a C# function on the web (enclosed below) that
looked well written and properly closes everything.However I was SHOCKED to
find that I ran into the SAME EXACT PROBLEM. The first time the service
starts up it works fine. But on all subsequent attempts I get this error
about the file being in use.Everything appears to be in order. What am I
missing here?? This is driving me nuts so any help is greatly
appreciated!!Thanks!![for reference here's the code I found on the net which
exhibits the same issue I get when using the simplier .DownloadFile method [SNIP CODE]

Mike,

you should really try using the 'using' statement on those streams (it'll close and dispose automatically) and it might be a good idea to use StreamWriter for localStream and StreamReader for remoteStream.
Have you tried stepping through the code and wait for localStream.close() to execute?

Leon
 

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