Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#文件系统监视程序和后台工作程序_C#_Backgroundworker_Filesystemwatcher - Fatal编程技术网

c#文件系统监视程序和后台工作程序

c#文件系统监视程序和后台工作程序,c#,backgroundworker,filesystemwatcher,C#,Backgroundworker,Filesystemwatcher,我想同步我的文件夹,所以我有10个Filesystemwatcher和4个Backgroundworkers。 这个想法是,一个观察者可以调用4个工作者中的每一个,但我希望观察者选择一个活跃的自由工作者,其他人不应该被触发 实验:工人1被解雇,2-4不被解雇 我做错了什么 这是我的密码 private void watcher1_OnChanged(object source, FileSystemEventArgs e) { // Fil

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

实验:工人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;
                }
            }
        }
private void watcher1\u一旦更改(对象源、文件系统目标)
{
//文件名
字符串文件=e.FullPath;
//刷新App.Config
ConfigurationManager.RefreshSection(“应用设置”);
//检查工作进程是否处于活动状态
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”]);
//观察家努默
字符串watcherNr=“Watcher 1”;
//调用worker的参数
列表参数=新列表();
参数。添加(文件);
Add(watcher1_destinationPath);
Add(watcher1\u sourcePath);
参数.Add(watcherNr);
布尔成功=假;
而(!success==true)
{
尝试
{
使用(Stream=newfilestream(file,FileMode.Open))
{
如果(worker1Active==true&&worker1.IsBusy!=true)
{
worker1.RunWorkerAsync(参数);
成功=真实;
打破
}
if(worker2Active==true&&worker2.IsBusy!=true)
{
worker2.RunWorkerAsync(参数);
成功=真实;
打破
}
如果(worker3Active==true&&worker3.IsBusy!=true)
{
worker3.RunWorkerAsync(参数);
成功=真实;
打破
}
if(worker4Active==true&&worker4.IsBusy!=true)
{
worker4.RunWorkerAsync(参数);
成功=真实;
打破
}
}
}
抓住
{
成功=错误;
}
}
}

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

下面是关于如何在c#中使用线程池的链接

此外,如果您希望一次只使用四个线程继续工作,则可以设置线程中的最大线程数

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

以下是使用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,并将创建、重命名、更改和删除的事件挂接到同一个eventhandler(FileWatcher\u Changed)

为什么不使用线程池?Aman是这么说的。这不是线程安全的。如果所有的工人都很忙,而且工作堆积如山,你会怎么做?您应该使用队列对工作进行排队,并使用线程池拾取工作。您可以让filesystemwatcher为您将工作排队,线程池可以设置为多个工作线程,以便在后台执行工作。如果您愿意,我可以制作一个小示例应用程序并在此处发布代码。线程的真正原因是您希望最小化事件回调中的工作量,否则您可能会丢失文件系统更改,这意味着我有一个方法(worker),线程池控制有多少线程并行工作。在这种情况下,队列中有多少个作业@安德烈:你可以有不同的工作方法。可以有多个线程并行运行。如果只想运行一个任务,请使用SerialWorkQueue。我有一个示例代码。这将在单个线程中运行所有内容,并等待一个工作线程完成,然后再继续下一个工作线程。@Andre,检查我的答案。您可以将多个FileSystemWatcher连接到eventhandler,只需将EventArgs类排队即可。然后在worker运行的ProcessFile方法中,您可以基于changetypeGreat调用任何其他方法。谢谢你1000次。@Andre,如果这是你要找的,请标出答案。是stackoverflow和我自己。谢谢