好的我有一个应用程序根据另一个应用程序创建的文件生成一些合同。
我已经实现了一个filewatcher来监视正在创建的文件,然后启动backgroundworker
进程以根据文件名创建合同。
我遇到的问题是在后台工作进程中我将EnableRaisingEvents
设置为false,以便应用程序在第一个运行时不会开始处理不同的一组合同(它也是为了停止调用背景工作者虽然它正在运行,因为它不能同时运行2件事!)。
一切正常,另一个应用程序创建一个文件,filewatcher选择它并开始处理,问题是当处理完成后,filewatcher被重新启用但我认为它不会拾取在{时创建的任何文件{1}}是假的 - 所以如果创建初始文件以生成合同的应用程序碰巧在我的应用程序正在处理时创建另一个文件,那么它就会被遗忘。那有意义吗?这周围最好的方法是什么?
我曾考虑过另一个进程,当初始合同创建完成后,会在目录中查找在filewatcher被禁用的时间之间创建的其他文件,如果没有,则会重新启用filewatcher但是我想知道是否有更简单的方法可以做到这一点?
答案 0 :(得分:0)
您可以在任务中拆分流程。一个任务是FileRegistrator,它接收新文件,将它们注册到数据库中。它一直运行,不需要EnableRaisingEvents为false。
下一个任务是ProcessorTask(或任何名称),它将查询数据库,找到第一个并处理它。它会定期查询数据库以查看是否注册了新文件。
您可以在Windows服务中使用Quartz.NET调度程序实现这个小处理器。
(我之前做过同样的事,但我没有使用FileSystemWatcher)
答案 1 :(得分:0)
BlockingCollection会这样做。
保持FileWatcher热,并将其添加到阻止集合中
消费者只是一次处理一个集合。
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);
}
}
}
}