0

我正在用 C# 编码的 Visual Studio 2012 中为 Windows 编写软件。

通过使用 FileSystemWatcher 类,我正在监视目录的更改:如果将一个或多个新文件添加到目录中,则 FileSystemEventHandler 类会触发一个事件。

此事件将文件名添加到数组中。

然后我想处理数组,即:处理数组中的每个文件(通过文件名访问)并对文件做一些事情。

现在:我需要确保文件处理按顺序进行。查看文件 1,处理它,只有在完成后,查看文件 2,处理它,等等。

每个文件的文件处理大约需要 5 秒。同时,可以将新文件添加到目录中,因此 FileSystemEventHandler 类将因这些更改而触发。但我不希望这种情况发生 - 一次应该总是只有一个文件被处理 - 无论更改事件被触发多少次!

谁能为此提供一个模式(或代码片段),好吗?!

4

5 回答 5

2

我认为下课是最佳的,

BlockingCollection<T> 班级

为实现 IProducerConsumerCollection 的线程安全集合提供阻塞和边界功能。

它充当并发队列,您可以使用任务异步处理项目。

替代方案是ConcurrentQueue<T>,但 BlockingCollection 为您提供了两个重要功能

它是线程安全的

当您调用时Take(),它会为您阻塞(即等到队列中有东西),因此您不必使用 ManualResetEvents 等编写任何代码,这是一个很好的简化。

于 2013-10-22T07:35:56.637 回答
1

您想要的模式是 FileSystemEventHandler 只是将文件名添加到共享队列中。

然后这个队列可以被另一个线程独立监视,然后从队列中删除项目并处理它们。

这样,在您处理文件时,无需“停止”事件处理程序添加项目。它可以继续添加更多,并且不会影响工作线程。

我建议使用 ConcurrentQueue 类来管理要处理的文件列表。

Microsoft 的以下示例代码显示了如何使用 BlockingCollection(包装 ConcurrentQueue)来实现此目的:

http://msdn.microsoft.com/en-us/library/dd997371.aspx

于 2013-10-22T07:34:23.800 回答
1

您也可以选择使用RX 框架

像这样的东西:

public static Tuple<FileSystemWatcher, Task> Watch(this string path, Action<string> processNewFile)
{
    var watcher = new FileSystemWatcher(path) {EnableRaisingEvents = true};
    return
        Tuple.Create(
            watcher,
            Observable
                .FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
                    handler => watcher.Created += handler,
                    handler => watcher.Created -= handler)
                .Select(pattern => pattern.EventArgs.FullPath)
                .ForEachAsync(processNewFile));
}

这种方法是异步友好的、简洁的,并且无需编写大量样板代码。

于 2013-10-22T07:51:44.843 回答
0

您需要使用Queue。队列需要在单独的线程中处理。因此您可以在不干扰监视文件夹事件的情况下处理文件数组列表

于 2013-10-22T07:36:52.680 回答
0

您可以设置一个布尔变量,如果另一个文件正在处理,则设置为 true,处理完成后设置为 false。同时,如果 FileSystemEventHandler 触发一个新事件,它会检查变量,如果设置为 true,它将等待。否则,将变量本身设置为 true 并继续。

于 2013-10-22T07:37:26.017 回答