Solution: The process cannot access the file [filename] because it is being used by another process.
Don't you just hate it when you get a programming error that pisses away your entire day? I had one of those errors today. I'm going to share with you my findings so you only piss away half-of-a-day. :-P
I've been writing a quote generating web application for .NET 2.0. This application uses Crystal Reports XI to generate a printer friendly quote to PDF using the ReportDocument.ExportToDisk method. That PDF gets emailed to a list of people. The application seemed to be working great until today. I was writing some code to delete those PDF files and I got this error:
The process cannot access the file '[filename]' because it is being used by another process.
I started troubleshooting by assuming the CrystalReportSource.ReportDocument had inadvertently kept the exported files open. I start using dispose methods against the crystal objects, GC.Collect, etc... I started looking for tids on Business Objects' web site about this issue, or discussions about known bugs, etc. I brought out the BIG GUNS and downloaded SysInternals FileMon from Microsoft to see exactly what was going on. Here is a summary of the results.
w3wp.exe:5800 CREATE C:\QMS\Quotes\1005.pdf
w3wp.exe:5800 WRITE C:\QMS\Quotes\1005.pdf
w3wp.exe:5800 CLOSE C:\QMS\Quotes\1005.pdf
w3wp.exe:5800 OPEN C:\QMS\Quotes\1005.pdf
w3wp.exe:5800 READ C:\QMS\Quotes\1005.pdf
As you can see, it created the PDF, it wrote the PDF, it closed the PDF (expected). Then, there was an unexpected Open, Read, without close immediately after the file was created. Obviously, we've found the problem. I made a last ditch effort to export the PDF to a temporary location, use System.IO.File to copy the file to the actual location, and that file was STILL being opened without a corresponding CLOSE.
HERE WAS THE SOLUTION:
I looked a little lower in my code and found a routine that emails the file using Microsoft's System.Net.Mail.MailMessage. AHHHHH HA! The Attachments.Add method opened the file to attach it to the MailMessage. After using the System.Net.Mail.SmtpClient to send the message, the message object was never cleared, even after garbage collection. By changing my code to do this:
Dim msg as New System.Net.Mail.MailMessage()
... code to create message and attach files
... code to send with smtpclient
msg.Dispose() ' This was the solution!
... the file was then closed during the disposal of the message object, and I became a happy programmer.
So, if you get this error, start thinking about EVERY process that touches your files and experiment with Dispose. I highly recommend FileMon to pinpoint where the code went wrong.
- Blog category: