0

好的,我有一个应用程序可以根据另一个应用程序创建的文件生成一些合同。

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

我遇到的问题是,在后台工作进程中,我设置EnableRaisingEvents为 false 以便应用程序在第一个合同运行时不会开始处理不同的合同集(这也是在后台工作进程运行时停止调用它不能一次运行两件事!)。

一切正常,其他应用程序创建一个文件,filewatcher 将其拾取并开始处理,问题是处理完成后,filewatcher 被重新启用,但我认为它不会拾取任何在EnableRaisingEvents为 false 时创建的文件 - 并且因此,如果创建初始文件以生成合同的应用程序碰巧在我的应用程序处理时创建了另一个文件,它将被留下。那有意义吗?最好的解决方法是什么?

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

4

2 回答 2

0

您可以将流程拆分为任务。一项任务是 FileRegistrator ,它拾取新文件,将它们注册到数据库中。它一直在运行,无需将 EnableRaisingEvents 设置为 false。

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

您可以在 Windows 服务中使用 Quartz.NET 调度程序来实现这个小处理器。

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

于 2013-04-10T12:02:59.740 回答
0

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);
            }
        }
    }
}
于 2013-04-10T13:12:00.390 回答