0

I've seen this question before but with lots of answers and I don't know what's the best solution to solve this.

My scanner is running fine after a fresh start. It's scanning a directory for textfiles and the it has to do somthing with the file. The first file is always working but after the first file it becomes a gamble

Please help

Code

    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\Data\IN";
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite| NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.Filter = "*.txt";
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.EnableRaisingEvents = true;


    public void OnChanged(object source, FileSystemEventArgs e)
    {
         try  
            {
                eventLog1.WriteEntry("Processing file : "+e.FullPath);
                System.Collections.Generic.IEnumerable<String> lines = File.ReadAllLines(e.FullPath, System.Text.Encoding.Default);
                System.Threading.Thread.Sleep(100);
                if (File.Exists(Path.ChangeExtension(e.FullPath, ".old"))) 
                File.Delete(Path.ChangeExtension(e.FullPath, ".old"));
                File.Move(e.FullPath, Path.ChangeExtension(e.FullPath, ".old"));
                }
              catch (Exception ex)
              {
             eventLog1.WriteEntry("change : " + String.Concat(ex.Message, ex.StackTrace), EventLogEntryType.Error);
             return;
         }
    }

The error is this :

    cannot get access to file  C:\Data\IN\kopie.txt because its beeing used by another      proces.   
user1723982
  • 69
  • 1
  • 1
  • 4
  • 1
    It says it all in the error message, you are trying to access a file that is being used by something else. Not sure what the code is trying to do, but if the file you are inspecting is only being used by this program, I would suspect the program is not closing a file properly when it needs to. – AnotherUser Jun 24 '14 at 17:59

1 Answers1

0

MSDN explicitly says that:

Common file system operations might raise more than one event. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised. Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher.

It means that your own operation may cause the Event to raise - you got the event - you move the file - new event arises - you try to read it while it is being moved - Exception. That's how it could happen.

Also do not use System.Threading.Thread.Sleep(100);. Sometimes there is really no other way to check for a condition other than to wait and check and there is no direct way(that I know of) in .NET to do it more clearly - Is there a way to check if a file is in use?.

But you use your Sleep in the handler - who knows what and how could change during the sleep. Event is something that you should react and not something you should sleep on(what if many files are changed at once - each file's handling will take a minimum of 0.1 second).

I'd recommend you to create some queue of events and handle them out of the event. But you still have to understand what actions raise what events - and it could be done only through documentation and practice.

Community
  • 1
  • 1
Eugene Podskal
  • 10,270
  • 5
  • 31
  • 53