MD5CryptoServiceProvider - File Not Closing

J

John Talli

In the following function, it seems the file (p_s_FilePath_FileName) is NOT being
release. Can anyone tell me why the file is not being released? If I comment out the
program line that calls this function, the file can be processed in later processing. I
think I have tried everything I can including Threading.Thread.Sleep(2) [I was
desperate.] What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being used by
another process.

Thanks

=================
FUNCTION THAT IS NOT CLOSING THE FILE
=================
using System.Security.Cryptography;

public string GetMD5Checksum_From_File(string p_s_FilePath_FileName)
{
_bool_Is_Error = false;
StringBuilder sb = new StringBuilder();
try
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);
md5.ComputeHash(fs);
fs.Close();
byte[] hash = md5.Hash;
//byte hByte = 0;
foreach (var h2Byte in hash)
{
sb.Append(string.Format("{0:X2}", h2Byte));
}
fs.Dispose();
fs = null;
md5 = null;
GC.Collect();
}
catch (Exception ex)
{
_s_Err_Msg = ex.Message.ToString().Trim(); << error msg stuff
sb.Append("".ToString()); << error msg stuff
_bool_Is_Error = true; << error msg stuff
}
return sb.ToString();
 
A

Arne Vajhøj

John said:
In the following function, it seems the file (p_s_FilePath_FileName) is
NOT being release. Can anyone tell me why the file is not being
released? If I comment out the program line that calls this function,
the file can be processed in later processing. I think I have tried
everything I can including Threading.Thread.Sleep(2) [I was desperate.]
What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is
being used by another process.
FileStream fs = new FileStream(p_s_FilePath_FileName,
FileMode.Open, FileAccess.Read, FileShare.Read, 8192);

This FileStream is never closed.
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);

This FileStream is closed.
fs.Close();
Here.

fs.Dispose();

One of Close or Dispose should be enough, so I would say either
explicit Close or implicit Dispose via using.
fs = null;


That should be completely unnecessary.

Arne
 
A

Anthony Jones

John Talli said:
In the following function, it seems the file (p_s_FilePath_FileName) is
NOT being release. Can anyone tell me why the file is not being released?
If I comment out the program line that calls this function, the file can
be processed in later processing. I think I have tried everything I can
including Threading.Thread.Sleep(2) [I was desperate.] What am I doing
wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being
used by another process.

Thanks

=================
FUNCTION THAT IS NOT CLOSING THE FILE
=================
FileStream fs = new FileStream(p_s_FilePath_FileName,
FileMode.Open, FileAccess.Read, FileShare.Read, 8192);
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
<snip>

You are creating two filestreams on the same file and assigning them to a
single variable. Hence you can only close one of the streams (the second),
the other stream will sit in the heap and will not be closed until the GC
cleans up the garbage.

Why are you opening the stream twice?
 
J

John Talli

What line of source code does the error indicate as having the problem.

It isn't until a function in another program tries to use the file again that
the error ( "... it is being used by another process.") occurs. I also put
GC.Collect \ Wait States in that other program also.

rossum said:
In the following function, it seems the file (p_s_FilePath_FileName) is NOT being
release. Can anyone tell me why the file is not being released? If I comment out the
program line that calls this function, the file can be processed in later processing.
I
think I have tried everything I can including Threading.Thread.Sleep(2) [I was
desperate.] What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being used by
another process.
What line of source code does the error indicate as having the
problem.

Thanks

=================
FUNCTION THAT IS NOT CLOSING THE FILE
=================
using System.Security.Cryptography;

public string GetMD5Checksum_From_File(string p_s_FilePath_FileName)
{
_bool_Is_Error = false;
StringBuilder sb = new StringBuilder();
try
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
This line opens the file into a FileStream.
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);
This line attempts to reopen the same file. Try commenting out this
line and see if things work better.

rossum
md5.ComputeHash(fs);
fs.Close();
byte[] hash = md5.Hash;
//byte hByte = 0;
foreach (var h2Byte in hash)
{
sb.Append(string.Format("{0:X2}", h2Byte));
}
fs.Dispose();
fs = null;
md5 = null;
GC.Collect();
}
catch (Exception ex)
{
_s_Err_Msg = ex.Message.ToString().Trim(); << error msg stuff
sb.Append("".ToString()); << error msg stuff
_bool_Is_Error = true; << error msg stuff
}
return sb.ToString();
 
J

John Talli

I was putting Closes, Disposes, and GC.Collects all over the place trying to get it to
close the file.
(Desperation on my part.)

Arne Vajhøj said:
John said:
In the following function, it seems the file (p_s_FilePath_FileName) is NOT being
release. Can anyone tell me why the file is not being released? If I comment out the
program line that calls this function, the file can be processed in later processing.
I think I have tried everything I can including Threading.Thread.Sleep(2) [I was
desperate.] What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being used by
another process.
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);

This FileStream is never closed.
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);

This FileStream is closed.
fs.Close();
Here.

fs.Dispose();

One of Close or Dispose should be enough, so I would say either
explicit Close or implicit Dispose via using.
fs = null;


That should be completely unnecessary.

Arne
 
J

John Talli

Why are you opening the stream twice?

You've got me. I guess I have looked at the piece of code for so longer (trying to
close the file) that I never spotted that redundant piece of code. (I think I have
become cross-eyed now.)

But as you said, the GC cleans it up and the file should automatically close. I will
remove the duplicate piece of code and let everyone know if that works.


Anthony Jones said:
John Talli said:
In the following function, it seems the file (p_s_FilePath_FileName) is NOT being
release. Can anyone tell me why the file is not being released? If I comment out the
program line that calls this function, the file can be processed in later processing.
I think I have tried everything I can including Threading.Thread.Sleep(2) [I was
desperate.] What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being used by
another process.

Thanks

=================
FUNCTION THAT IS NOT CLOSING THE FILE
=================
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);
<snip>

You are creating two filestreams on the same file and assigning them to a single
variable. Hence you can only close one of the streams (the second), the other stream
will sit in the heap and will not be closed until the GC cleans up the garbage.

Why are you opening the stream twice?
 
J

John Talli

Thanks to Anthony and everyone else for solving the problem.

I have reposted the CORRECTed piece of code just below. Anthony spotted the DUPLICATE
piece of code (and I have no idea why I wrote it twice). Apparently one of the
instances of the file opening is not being closed during GC.Collect even though it is
explicitly be closed\nulled\disposed and told it is not wanted anymore. I would love to
say it is a GC error but I really think it was a programming error on my part. The GC
closed the second instance of the file but the first instance stayed open.

Now I can go around my code and remove all the times I wrote GC.Collect() and
Threading.Thread.Sleep(2) out of desperation (which still did not work).

THANKS AGAIN
======
VERSION THAT WORKS
======

using System.Security.Cryptography;

public string GetMD5Checksum_From_File(string p_s_FilePath_FileName)
{
_bool_Is_Error = false;
StringBuilder sb = new StringBuilder();
try
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
//fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);
md5.ComputeHash(fs);
fs.Close();
byte[] hash = md5.Hash;
//byte hByte = 0;
foreach (var h2Byte in hash)
{
sb.Append(string.Format("{0:X2}", h2Byte));
}
fs.Dispose();
fs = null;
md5 = null;
GC.Collect();
}
catch (Exception ex)
{
_s_Err_Msg = ex.Message.ToString().Trim();
_bool_Is_Error = true;
}
return sb.ToString();
}


Anthony Jones said:
John Talli said:
In the following function, it seems the file (p_s_FilePath_FileName) is NOT being
release. Can anyone tell me why the file is not being released? If I comment out the
program line that calls this function, the file can be processed in later processing.
I think I have tried everything I can including Threading.Thread.Sleep(2) [I was
desperate.] What am I doing wrong.

The error is :
The process cannot access the file 'C:\temp\Files.xml' because it is being used by
another process.

Thanks

=================
FUNCTION THAT IS NOT CLOSING THE FILE
=================
FileStream fs = new FileStream(p_s_FilePath_FileName, FileMode.Open,
FileAccess.Read, FileShare.Read, 8192);
fs = new FileStream(p_s_FilePath_FileName, FileMode.Open, FileAccess.Read,
FileShare.Read, 8192);
<snip>

You are creating two filestreams on the same file and assigning them to a single
variable. Hence you can only close one of the streams (the second), the other stream
will sit in the heap and will not be closed until the GC cleans up the garbage.

Why are you opening the stream twice?
 
J

John Talli

Thanks again for everyone's help.

While I was awaiting the help, I wrote a workaround function that takes a String instead
of a FileName that does the same thing. Here is the code for that function:

public string GetMD5Checksum_From_String(string p_s_String2Hash)
{
_bool_Is_Error = false;
StringBuilder sb = new StringBuilder();
try
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] data = md5.ComputeHash(Encoding.Default.GetBytes(p_s_String2Hash));
for (int i = 0; i < data.Length; i++)
{
sb.Append(data.ToString("x2"));
}
md5 = null;
}
catch (Exception ex)
{
_s_Err_Msg = ex.Message.ToString().Trim();
sb.Append("".ToString());
_bool_Is_Error = true;
}
return sb.ToString();
}
 
A

Anthony Jones

John Talli said:
Thanks to Anthony and everyone else for solving the problem.

I have reposted the CORRECTed piece of code just below. Anthony spotted
the DUPLICATE piece of code (and I have no idea why I wrote it twice).
Apparently one of the instances of the file opening is not being closed
during GC.Collect even though it is explicitly be closed\nulled\disposed
and told it is not wanted anymore. I would love to say it is a GC error
but I really think it was a programming error on my part. The GC closed
the second instance of the file but the first instance stayed open.

Now I can go around my code and remove all the times I wrote GC.Collect()
and Threading.Thread.Sleep(2) out of desperation (which still did not
work).

I doubt the GC.Collect closes the second instance, that will be your own
call to close that does that note also that dispose is synonymous with close
hence only one is actually needed.

I perhaps should have clarified that objects that have a finalizer (such as
FileStream) will take even longer to be cleaned up. The GC will move any
such garbage objects to a finalizer queue but it isn't responsible for
emptying that queue. Over time, application activity permitting, .NET will
run through the finalizer queue calling the finalize method on each object
found there. Only when that happens will any unmanaged resource be
released.
 

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