5

I'm having a problem working with filesystemwatcher, it's driving me crazy.

Turns out I'm watching for new text files in a folder, when the Created Event is raised, I basically read it using the following code:

string txtTemp = File.ReadAllText(MyFilePath);

After that, I process the data in the txtTemp string, basically I read it's lines & store the data on a DB, pretty simple isn't it?

The problem is when an exception is raised in this process (let's say db connection failed), it doesn't matter if I catch it because for the next coming files the app will throw an exception saying

"The process cannot access the file 'theNewComingFile.txt' because it is being used by another process."

How come the new created file could be in use if it hasn't even been opened or read it? And the application keeps throwing this "process cannot access the file" exception for all new files.

The only thing we can do is to close and reopen the application, this resets the app and everything works fine again until an exception of any type is raised again> (gosh!)

Any ideas? any workaround? any thoughts? any suggestions any... anything? hehehehe =)

Thanks dudes !!

franko_camron
  • 1,288
  • 4
  • 14
  • 30
  • Is it possible you're setting up another FileSystemWatcher in case of an exception, and they are both racing to handle the same file? Could you post your event handling code, as well as the FileSystemWatcher setup code? – zmbq Nov 21 '11 at 20:12
  • [`File.ReadAllText()`](http://msdn.microsoft.com/en-us/library/ms143368.aspx): "Opens a text file, reads all lines of the file, **and then closes the file**.". It shouldn't happen as long as the exception isn't raised from there. Can't you try a StreamReader to read the file? – CodeCaster Nov 21 '11 at 20:16
  • Hi, give more detial, just like [this](http://stackoverflow.com/questions/699538/file-access-error-with-filesystemwatcher-when-multiple-files-are-added-to-a-dire) question. – OnesimusUnbound Nov 21 '11 at 20:30
  • @CodeCaster yes, initially I was using the streamread, same problem with it – franko_camron Nov 21 '11 at 23:34
  • More code... OK there's not much to show but I'll paste it @jtm001 – franko_camron Nov 21 '11 at 23:38
  • I have the same problem because file reading isn't finished while the watcher tries to access it from a separate thread. – Ray Chakrit Mar 21 '23 at 12:37

4 Answers4

5

you can start your investigation using the Sysinternals Process Explorer. It will give you more details, particularly on which process holds the file.

OnesimusUnbound
  • 2,886
  • 3
  • 30
  • 40
2

The Created event is fired before the file is finished being completely written.

From MSDN:

The OnCreated event is raised as soon as a file is created. If a file is being copied or transferred into a watched directory, the OnCreated event will be raised immediately, followed by one or more OnChanged events.

So getting the exception you describe would be fairly normal. When I've faced this situation, I basically test the file first to see if I can access it or not. Here is the function I use:

  private static bool GetExclusiveAccess(string filePath)
  {
     try
     {
        using (FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write))
        {
           file.Close();
           return true;
        }
     }
     catch (IOException)
     {
        return false;
     }
  }

If you don't have access, then you'll need to wait and check again.

Russell McClure
  • 4,821
  • 1
  • 22
  • 22
  • Nop, I'm not coping the file, it is created from a different app, but let's say that was the problem, why if I restart it after the exception it works fine? – franko_camron Nov 21 '11 at 23:36
  • It doesn't have to do with copying the file. Any file that comes into existence first has to be created and then it is "filled" up with content and then closed. All during the "filling" it is locked by the file creator. But the FileSystemWatcher fires the OnCreated event right after creation. So you have a race condition between the creator of the file and the code responding to the OnCreated event. If it's a super tiny file, then the filling might be done by the time your thread gets the OnCreated. But normally you will see what you described. The file creator is still "filling" it up. – Russell McClure Nov 21 '11 at 23:44
  • Thanks Russell McClure, I'll be testing this today and try to implement your solution, then let you know. Thanks again ! – franko_camron Nov 22 '11 at 16:57
2

It may be the act of opening the file changes the last-read timestamp: this could cause a loop.

You might want to try changing your design so that the events are placed onto a queue if (and only if) the file isn't already queued for processing. You can then trap for exceptions, etc., under proper control on the other thread without getting in the way of the Watcher.

[I've seen some very interesting corner cases with FileSystemWatcher in the past - it can be a bit of a beast when cornered. One (a while back) caused a not-quite-reproducible blue-screen hang in Windows Server 2003 when an internal buffer overflowed because it was swamped with events. Best be careful.]

Jeremy McGee
  • 24,842
  • 10
  • 63
  • 95
-1

A work-around is simple - put your watcher in its own AppDomain, tear down the AppDomain and restart if you handle an exception. This will most probably fix your problem. But why does it happen? I'll have to think about it a little, and maybe find something.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • 3
    Let's put a boat in our boat for when our boat sinks. And what if the second boat sinks? Put in another boat! – CodeCaster Nov 21 '11 at 20:12
  • They're called lifeboats. Every ship has them in case the ship sinks. Anyway... if FileSystemWatcher is critically flawed, then this suggestion may be a legitimate option. Having said that, the isolation is probably unnecessary, because the problem is simply an open file handle. – Triynko Nov 28 '11 at 21:34