c#filesystemwatcher和backgroundworker

时间:2017-09-04 18:29:59

标签: c# backgroundworker filesystemwatcher

我想要同步我的文件夹,所以我有10个Filesystemwatcher和4个Backgroundworkers。 这个想法是,一个观察者可以调用4个工作者中的每一个,但我希望观察者选择一个活跃的自由工作者,其他人不应该被触发。

Exp:工人1被解雇,2-4人没有。

我在这里做错了什么?

这是我的代码

        private void watcher1_OnChanged(object source, FileSystemEventArgs e)
        {
            // File Name
            string file = e.FullPath;

            // refresh App.Config
            ConfigurationManager.RefreshSection("appSettings");

            // Check Worker Active
            bool worker1Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker1Active"]);
            bool worker2Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker2Active"]);
            bool worker3Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker3Active"]);
            bool worker4Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker4Active"]);

            // Watcher Nummer
            string watcherNr = "Watcher 1";

            // Arguments to call worker
            List<object> arguments = new List<object>();
            arguments.Add(file);
            arguments.Add(watcher1_destinationPath);
            arguments.Add(watcher1_sourcePath);
            arguments.Add(watcherNr);

            bool success = false;

            while (!success == true)
            {
                try
                {
                    using (Stream stream = new FileStream(file, FileMode.Open))
                    {

                            if (worker1Active == true && worker1.IsBusy != true)
                            {
                                worker1.RunWorkerAsync(arguments);
                                success = true;
                                break;
                            }

                            if (worker2Active == true && worker2.IsBusy != true)
                            {
                                worker2.RunWorkerAsync(arguments);
                                success = true;
                                break;
                            }

                            if (worker3Active == true && worker3.IsBusy != true)
                            {
                                worker3.RunWorkerAsync(arguments);
                                success = true;
                                break;
                            }

                            if (worker4Active == true && worker4.IsBusy != true)
                            {
                                worker4.RunWorkerAsync(arguments);
                                success = true;
                                break;
                            }
                    }
                }
                catch
                {
                    success = false;
                }
            }
        }

2 个答案:

答案 0 :(得分:1)

编辑:确保在处理过程中锁定文件并在处理之前检查锁定。如果您有多个工作人员处理单个文件,您将遇到问题。只需确保在要处理的文件被锁定时重新排队作业。它将自动重新排队,直到它解锁。当然,你需要再次解锁它。

以下是使用ThreadPool的示例应用: ThreadPool是线程安全的,这意味着当它完成它的工作时,它会在不同的线程中执行它,这将使您的UI保持响应而不会阻塞。

玩得开心!

using System;
using System.IO;
using System.Threading;

namespace FileWatcherThreadApp
{
    class Program
    {

        static void Main(string[] args)
        {
            FileSystemWatcher fileWatcher = new FileSystemWatcher(@"C:\Users\BertSinnema\watch");

            //Enable events
            fileWatcher.EnableRaisingEvents = true;

            //Add event watcher
            fileWatcher.Changed += FileWatcher_Changed;
            fileWatcher.Created += FileWatcher_Changed;
            fileWatcher.Deleted += FileWatcher_Changed;
            fileWatcher.Renamed += FileWatcher_Changed;

            var maxThreads = 4;

            // Times to as most machines have double the logic processers as cores
            ThreadPool.SetMaxThreads(maxThreads, maxThreads * 2);


            Console.WriteLine("Listening");
            Console.ReadLine();

        }

        //This event adds the work to the Thread queue
        private static void FileWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            ThreadPool.QueueUserWorkItem((o) => ProcessFile(e));
        }

        //This method processes your file, you can do your sync here
        private static void ProcessFile(FileSystemEventArgs e)
        {
            // Based on the eventtype you do your operation
            switch (e.ChangeType)
            {
                case WatcherChangeTypes.Changed:
                    Console.WriteLine($"File is changed: {e.Name}");
                    break;
                case WatcherChangeTypes.Created:
                    Console.WriteLine($"File is created: {e.Name}");
                    break;
                case WatcherChangeTypes.Deleted:
                    Console.WriteLine($"File is deleted: {e.Name}");
                    break;
                case WatcherChangeTypes.Renamed:
                    Console.WriteLine($"File is renamed: {e.Name}");
                    break;
            }
        }
    }


}

如果要唤醒多个文件夹,只需添加另一个FileSystemWatcher并将Created,Renamed,Changed和Deleted事件挂钩到同一个事件处理程序(FileWatcher_Changed)

答案 1 :(得分:0)

你应该使用ThreadPool。这将使您的代码看起来更干净,这是您应该使用的线程机制。它会将任务放在其中一个空闲线程上,如果所有线程都忙,那么它将等待其中一个线程空闲。

以下是有关如何在c#中使用ThreadPool的链接。

https://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx https://www.dotnetperls.com/threadpool

此外,如果您想一次只使用四个线程,则可以设置最大值。线程中的线程 Here is how to do it.