监视文件的最佳方式

本文关键字:方式 最佳 文件 监视 | 更新日期: 2023-09-27 18:08:21

我有一个应用程序,它基于另一个应用程序创建的文件生成一些合约。

我已经实现了一个filewatcher来监视正在创建的文件,然后它启动一个backgroundworker进程来创建基于文件名的合约。

我遇到的问题是,在后台工作进程中,我将EnableRaisingEvents设置为false,这样应用程序就不会开始处理一组不同的合同,而第一个正在运行(这也是为了停止调用后台工作,而它正在运行,因为它不能一次运行2件事!

所有工作都很好,其他应用程序创建一个文件,filewatcher拾取它并开始处理,问题是,当处理完成时,重新启用filewatcher,但我认为它不会拾取EnableRaisingEvents为假时创建的任何文件-因此,如果创建初始文件的应用程序生成合同,则创建另一个文件,而我的应用程序正在处理它将被留下。明白了吗?最好的解决办法是什么?

我曾想过有另一个过程,当初始合同创建完成后,将在目录中查找文件观察器被禁用的时间之间创建的其他文件,如果没有,它将重新启用文件观察器,但我想知道是否有更简单的方法来做到这一点?

监视文件的最佳方式

您可以将流程划分为多个任务。其中一个任务是FileRegistrator,它拾取新文件,将它们注册到数据库中。它一直运行,不需要将EnableRaisingEvents设置为false。

下一个任务是ProcessorTask(或任何名称),它将查询数据库,找到第一个并处理它。它将定期查询数据库,以查看是否注册了新文件。

您可以使用Quartz实现这个小处理器。. NET调度器

(我做了同样的一段时间前,但我没有使用FileSystemWatcher)

BlockingCollection就会这样做。
保持FileWatcher热,并让它添加到阻塞集合。
消费者每次只处理一个集合。

BlockingCollection类

class AddTakeDemo
{
    // Demonstrates: 
    //      BlockingCollection<T>.Add() 
    //      BlockingCollection<T>.Take() 
    //      BlockingCollection<T>.CompleteAdding() 
    public static void BC_AddTakeCompleteAdding()
    {
        // here you need to synch as it would have missed any 
        // new files while the application was down 
        // yes L-Three and any files that were not yet processed 
        // clearly the existing program is an end to end synch 
        // or no synch at all as it could be nothing else 
        using (BlockingCollection<int> bc = new BlockingCollection<int>())
        {
            // Spin up a Task to populate the BlockingCollection  
            using (Task t1 = Task.Factory.StartNew(() =>
            {
                //  FielSystem watcher                    
                bc.Add(fille);
            }))
            {
                // Spin up a Task to consume the BlockingCollection 
                using (Task t2 = Task.Factory.StartNew(() =>
                {
                    try
                    {
                        // Consume consume the BlockingCollection 
                        while (true) Console.WriteLine(bc.Take());
                        // process the file
                    }
                    catch (InvalidOperationException)
                    {
                        // An InvalidOperationException means that Take() was called on a completed collection
                        Console.WriteLine("That's All!");
                    }
                }))
                    Task.WaitAll(t1, t2);
            }
        }
    }
}