Search code examples
c#filesystemwatcherfile-locking

FileSystemWatcher.WaitForChanged returns, but there is still a lock on the file


I have a program that send a document to a pdf printer driver and that driver prints to a particular directory. After the print I want to attach the pdf to an e-mail (MailMessage) and send it off.

Right now, I send the document to the printer (wich spawns a new process) and then call a FileSystemWatcher.WaitForChanged(WaitForChangedResult.Created) but when the object is created, it's still not done "printing" and the pdf printer still has a lock on it, throwing an error when I try to attach that file to an e-mail.

  • I've considered a plain Thread.Sleep(2000) or whatever, but that's far less than ideal.
  • I considered putting the attachment code in a try/catch block and looping on failure, but again, that's just bad news.

I can't really think of an elegant solution.


Solution

  • WaitForChanges is waiting for the created event as you have it coded. As the document is being created, you get notified: this does not mean that the file is fully written and the lock removed.

    Sadly, I don't know of a good solution other than polling the file periodically. If there was a "all locks removed" event, you could use that, but there isn't.

    I just checked our PDF dump to directory code, and we only use WaitForChanges to detect the start of a new file. We then use an try {} catch {} where the catch (failing to get rights over the file) resubmits the attempt into the queue we maintain: each attempt "backs off" for longer, so the first try is 1 second after we detected the file, the second is 2 seconds later, then 4, 8, etc. This reduces the number retries on large files while still being fairly responsive to shorter files.