C# 启动的线程比预期的多

C# More threads starting than expected

我正在做一个必须观察目录的项目。这些文件将同时部署在该目录中。这意味着可以一次将 7000 个文件移动到目录中。如果将新文件添加到目录,我将使用 FileSystemWatcher 触发线程。如果我要移动少量文件(1-150 个文件,每个文件 20 KB),则会启动适量的线程。对于每个文件一个线程。一旦我粘贴了大量的这些文件,它就会显示启动的线程多于目录包含的线程。如您所见,我正在打印 "test" 并为每个线程启动一个计数器。最后,计数器的数字大于粘贴文件的数量。我粘贴的文件越多,计数器和粘贴文件之间的差异就越大。希望你能告诉我我做错了什么。

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++;
        }

按照这个article MSDN,Created事件可以解决你的问题

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;
}