2

I'm working on a project where i have to observe a directory. The files will be deployed in the directory at the same time. This means there could be 7000 files that will be moved to the directory at once. I'm using the FileSystemWatcher to trigger a thread if a new file ist added to the directory. If I'm moving a small amount of files (1-150 Files, 20 KB each) there are the right amount of threads starting. For each file one thread. As soon as I paste in a larger amount of these files, it's showing that there were more threads started than the directory contains. As you can see, I'm printing out "test" and a counter for each thread started. In the end, the counter is a higher number than the amount of pasted files. The more files I paste, the bigger is the difference between counter and pasted files. Hope you can tell me what I'm doing wrong.

public static void Main(string[] args)
        {
            Queue queue = new Queue();
            queue.Watch();
            while (true)
            {

            }
        }


        public void Watch()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = "directorypath\\";
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Filter = "*.*";
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
        }


        public void OnChanged(object source, FileSystemEventArgs e)
        {
            WaitForFile(e.FullPath);
            thread = new Thread(new ThreadStart(this.start));
            thread.Start();
            thread.Join();

        }


        private static void WaitForFile(string fullPath)
        {
            while (true)
            {
                try
                {
                    using (StreamReader stream = new StreamReader(fullPath))
                    {
                        stream.Close();
                        break;
                    }
                }
                catch
                {
                    Thread.Sleep(1000);
                }
            }
        }


        public void start()
        {
            Console.WriteLine("test" +counter);
            counter++;
        }
VSWizzard
  • 75
  • 4
  • 1
    Can you verify whether this is your issue? https://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice – Lasse V. Karlsen Sep 07 '18 at 11:48
  • why are you using `Thread` and not `Task`? There isn't really any good reason to handle `Thread` directly anymore. Use `Task.Run(() =>);` – Liam Sep 07 '18 at 11:48
  • 1
    How do you know that `watcher.Changed` isn't raised multiple times per file? Maybe you should just be subscribing to `watcher.Created`. – Matthew Watson Sep 07 '18 at 11:52
  • Thanks for the answers, I'll try these. I'm a beginner, I don't know when to use Task or Thread. – VSWizzard Sep 07 '18 at 11:54
  • @MatthewWatson unfortunately, the event won't fire if I'm using watcher.Created – VSWizzard Sep 07 '18 at 11:58
  • Have a look at [Task vs Thread differences](https://stackoverflow.com/questions/13429129/task-vs-thread-differences). I would strongly urge you to not use Thread at all. Task is a wrapper around Thread(s). It has numerous advantages not least of which `async` operations – Liam Sep 07 '18 at 12:12
  • Thanks. I'll check :) – VSWizzard Sep 07 '18 at 12:21

1 Answers1

1

Following this article MSDN, Created event can solve your problem

The M:System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs) event is raised as soon as a file is created. If a file is being copied or transferred into a watched directory, the M:System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs) event will be raised immediately

public void Watch()
{
      FileSystemWatcher watcher = new FileSystemWatcher();
      watcher.Path = "directorypath\\";
      watcher.NotifyFilter = NotifyFilters.LastWrite;
      watcher.Created += new FileSystemEventHandler(OnChanged);
      watcher.EnableRaisingEvents = true;
}
Antoine V
  • 6,998
  • 2
  • 11
  • 34
  • @Liam no need to look at your comment to response this question. .. This is a common problem.. Changed event isn't stable because it can be raised many times for just an action... – Antoine V Sep 07 '18 at 12:20
  • 1
    @Liam I think the docu contains the actual answer why the effect is seen: "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_ ." – Fildor Sep 07 '18 at 12:20
  • Just tried it with additional NotifyFilters. Working now with watcher.Created! – VSWizzard Sep 07 '18 at 12:20
  • @VSWizzard nice to help you – Antoine V Sep 07 '18 at 12:25