FileSystemWatcher 在队列中丢失文件

2024-06-18

我写了一个FileSystemWatcher为每个文件调用一次 pgm。但我的一些文件丢失了。我只用 10-11 个文件测试了代码。文件的删除会被正确记录,但创建不会被正确记录。某些文件未记录。我的 TASK 实施可能存在问题吗? 或者有什么问题吗Window Service?

 public static FileSystemWatcher m_Watcher;
        static BlockingCollection<string> blockingCollection = new BlockingCollection<string>();

protected override void OnStart(string[] args)
    {

        current_directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        //XmlDocument xml = new XmlDocument();
        try
        {
            strDir = ConfigurationManager.AppSettings["Directory"];
            fileMask = ConfigurationManager.AppSettings["FileMask"];
            strBatfile = ConfigurationManager.AppSettings["Batch"];
            strlog = ConfigurationManager.AppSettings["Log"];

            m_Watcher = new FileSystemWatcher();


            m_Watcher.Filter = fileMask;
            m_Watcher.Path = strDir + "\\";
            m_Watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                             | NotifyFilters.FileName | NotifyFilters.DirectoryName;




            m_Watcher.Created += new FileSystemEventHandler(OnCreated);

            m_Watcher.Deleted += new FileSystemEventHandler(OnDeleated);
            m_Watcher.Renamed += new RenamedEventHandler(OnRenamed);


            m_Watcher.EnableRaisingEvents = true;
        }
        catch (Exception exception)
        {
            CustomException.Write(CustomException.CreateExceptionString(exception.ToString()));
        }

    }
    public static void OnDeleated(object source, FileSystemEventArgs e)
    {
        try
        {

            Log.getLogger("File deleated- Filename :" + e.Name + " at timestamp : " + DateTime.Now.ToString(), strlog);
        }
        catch (Exception exception)
        {
            CustomException.Write(CustomException.CreateExceptionString(exception, e.Name));
        }
    }

    private static void OnCreated(object source, FileSystemEventArgs e)
    {

        var exceptions = new ConcurrentQueue<Exception>();

        try
        {

            Task.Factory.StartNew(() =>
            {
                try
                {

                    blockingCollection.Add(e.Name.ToString());

                }
                catch (Exception)
                {
                    throw;

                }

            });
            Task.Factory.StartNew(() =>
            {
                try
                {


                    foreach (string value in blockingCollection.GetConsumingEnumerable())
                    {
                        System.Diagnostics.Process.Start(Service1.strBatfile);
                        Log.getLogger("File Processed after executing batch:  Filename ->:" + value + " " + "Batch File Executed- > " + Service1.strBatfile + " at timestamp : " + DateTime.Now.ToString(), Service1.strlog);

                    }
                }
                catch (Exception)
                {
                    throw;
                }



            });


        }
        catch (AggregateException ae)
        {

            foreach (var ex in ae.InnerExceptions)
            {
                CustomException.Write(CustomException.CreateExceptionString(ex, e.Name));
            }
        }
        finally
        {
            m_Watcher.EnableRaisingEvents = true;
        }
    }

您正在使用许多线程/任务的方式来清楚地了解代码是如何工作的。正如您所说,您只想一次只处理一个文件,您只需要一个在类的生命周期内存在的线程/任务(我假设是应用程序)。

如果我剥离您的代码以在每当将文件放入某个文件夹时一次处理一个文件,这可能是一种实现。

请注意我如何拥有一个ConcurrentQueue以及读取该队列的一种方法。我也用这个方法WaitForExit https://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx在流程实例上防止运行多个流程。

    static ConcurrentQueue<string> filenames = new ConcurrentQueue<string>();

    static void QueueHandler()
    {
        bool run = true;
        AppDomain.CurrentDomain.DomainUnload += (s, e) =>
        {
            run = false;
            filenames.Enqueue("stop");
        };
        while(run)
        {
            string filename;
            if (filenames.TryDequeue(out filename) && run)
            {
                var proc = new Process();
                proc.StartInfo.FileName = filename;
                proc.Start();
                proc.WaitForExit(); // this blocks until the process ends....

            }
        }
    }

现在我们需要一个将运行的任务/线程QueueHandler和我们的FileSystemWatcher:

protected override void OnStart(string[] args)
{
        // have our queue reader method started
        Task.Factory.StartNew(QueueHandler);

        var fsw = new FileSystemWatcher();
        fsw.Created += (o, e) =>
            {
                // add a file to the queue
                filenames.Enqueue(e.FullPath);
                // optionally add polling for missed files
                // http://stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes
            };

        fsw.Path = ConfigurationManager.AppSettings["Directory"];
        fsw.NotifyFilter = NotifyFilters.FileName;
        fsw.Filter = ConfigurationManager.AppSettings["FileMask"];

        fsw.EnableRaisingEvents = true;
}

此实现最多将使用三个线程:一个主线程,一个用于创建事件FileSystemWatcher和一个用于QueueHandler相反,如果您的示例代码中每次在 FileSystemWatcher 正在监视的文件夹中创建新文件时都会启动新任务

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FileSystemWatcher 在队列中丢失文件 的相关文章

  • Cocoa 常量名称中的“k”代表什么[重复]

    这个问题在这里已经有答案了 可能的重复 Apple 的 API 中的 k 前缀表示什么 https stackoverflow com questions 675816 what does the k prefix indicate in
  • 如何获取网络服务的状态

    如何使用 C 获取 Web 服务的状态 无论是成功完成 失败还是待处理 private void button1 Click object sender EventArgs e var url servicsURL try var myRe
  • ExecuteNonQueryAsync 并在 SQL 事务中提交

    我正在寻求对我创建的一段代码的帮助 我正在尝试在事务中从 C 进行异步 SQL 调用 例如我可能正在更新或删除表中的行 这是我到目前为止所拥有的 但我似乎无法找到有关在事务中执行此操作的太多信息 根据我在这里所拥有的以及到目前为止我所理解的
  • 如何防止函数中的隐式转换?

    我正在编写一个实用程序类 其中包含 IsEquals 和 IsGreaterThanEquals 等接受 double 类型参数的方法 当我将浮点值发送到方法时 它们会隐式转换为双精度值并进行比较 我不希望这种事发生 当我发送 float
  • 限制并行工作的线程数量

    我正在创建一个函数 将文件从本地计算机复制到远程创建线程以并行执行 sftp def copyToServer does copy file given host name and credentials for i in hostsLis
  • 使用 C 序列化 double 和 float

    如何在 C 中序列化双精度数和浮点数 我有以下用于序列化短整型 整数和字符的代码 unsigned char serialize char unsigned char buffer char value buffer 0 value ret
  • 改装和授权标头

    目前 我正在向我的请求添加授权标头 如下所示 文件 SomeFile cs public interface ITestApi Get api test id Task
  • 安装/编译 pylzma(lzma python 绑定)

    我已经向作者提出了这个问题website http www joachim bauch de projects pylzma comment page 1 comment 5211 但我想我也可以在这里问 我一直在尝试使用以下设置安装 py
  • 预期在模拟中调用一次,但使用 Moq 时调用次数为 0 次

    我收到错误 在mock上调用一次 但是0次 下面是我的代码结构 public class GenerateAddress IGenerateAddress public GenerateAddress IAddress createAdd
  • gcc 的错误?模板类中友元函数的访问控制问题

    我有一个模板类 并在类中定义了一个友元函数 include
  • dotnet core 创建文件名中不含“CoreFxPipe_”的命名管道

    使用以下命令创建命名管道时命名管道客户端流 or 命名管道服务器流dotnet core 的类中 关联的 管道 看起来实际上是一个套接字 已自动将 CoreFxPipe 添加到文件名的前面 有没有一种非黑客的方法来防止这种行为 我只是希望文
  • 使用 C# 在 XML 文档中查找特定值的好方法是什么?

    我正在调用 Oracle 公开的 WebService 它接受 ItemID 的输入并向我返回相应的 Item Number 我想获取从响应中包含的 XML 返回的项目编号 XML 看起来像这样
  • COM Interop 挂起会冻结整个 COM 系统。如何取消COM调用

    我正在使用通过 COM Interop 包装器公开的第三方 dll 然而 其中一个 COM 调用经常冻结 至少不会返回 为了至少让我的代码更加健壮 我异步包装了调用 getDeviceInfoWaiter is a ManualResetE
  • 基于 C++ 组件的类

    Hi 我正在使用容器编写一个基于组件的类 但是在考虑了许多不同的方法之后 我找不到真正符合我想要的方法 这是总体思路的一个例子 我已经写的代码 Abstract class Component class Component public
  • 如何在迭代时从地图中删除?

    迭代时如何从地图中删除 喜欢 std map
  • 实现多个接口的 Service Fabric Actor 接口

    我正在构建一个应用程序 其中有多个不同的参与者类型 这些参与者类型对于某些不同的数据对象具有相同类型的行为 CRUD 为了更轻松地创建处理此问题的代码 我尝试创建一个这些参与者可以实现的接口 这意味着我有一个看起来像这样的参与者界面 pub
  • 如何在 C 中将 int 和数组保存在共享内存中?

    我正在尝试编写一个程序 让子进程在 Linux 上相互通信 这些进程都是从同一个程序创建的 因此它们共享代码 我需要它们能够访问两个整数变量以及一个整数数组 我不知道共享内存是如何工作的 我搜索过的每一个资源除了让我困惑之外什么也没做 任何
  • TPL架构问题

    我目前正在开展一个项目 我们面临并行处理项目的挑战 到目前为止没什么大不了的 现在来说说问题 我们有一个 ID 列表 我们定期 每 2 秒 为每个 ID 调用一个 StoredProcedure 需要单独检查每个项目的 2 秒 因为它们是在
  • SQlite 查询 - 如何检索多列数据?

    我很难在网上找到一个关于使用 xcode 和 cocos2dx 从 SQlite DB 获取多个值的工作示例 这是我的sql查询 char sql query 100 sprintf sql query SELECT FROM SQList
  • 类型与创建 CLR 存储过程不匹配

    我在程序集中有一个如下所示的方法 namespace MyNameSpace public class MyClass Microsoft SqlServer Server SqlProcedure public static void M

随机推荐