OK I have an application that produces some contracts based on a file that is created by another app.
好的,我有一个应用程序可以根据另一个应用程序创建的文件生成一些契约。
I have implemented a filewatcher to watch for the file being created and it then kicks off a backgroundworker
process to create the contracts based on the filename.
我已经实现了一个filewatcher来监视正在创建的文件,然后它启动一个backgroundworker进程来根据文件名创建契约。
The problem I am having is that during the background worker process I set EnableRaisingEvents
to false so that the app does not start to process a different set of contracts whilst the first is running (It's also to stop calling the background worker whilst it is running as it cant run 2 things at once!).
我的问题是,在后台工作进程我EnableRaisingEvents为false,这样应用程序就不会开始过程一组不同的合同首先是运行时(这也是停止调用后台工人同时运行,因为它不能跑2件事!)。
All works fine, the other app creates a file, filewatcher picks it up and starts processing, the problem is that when processing is finished the filewatcher is re-enabled but I assume it wont pick up any files that were created when EnableRaisingEvents
was false - and so if the application that creates the initial file to produce the contracts happens to create another file whilst my app is processing it will just be left. Does that make sense? And what is the best way round this?
没问题,其他应用程序创建了一个文件,filewatcher并开始处理,问题是,当处理完成filewatcher重新启用,但我认为它不会接任何文件时创建EnableRaisingEvents是假的,所以如果应用程序创建的初始文件生产合同创建另一个文件,而我的应用程序正在处理它就是离开了。这说得通吗?最好的方法是什么?
I had thought of having another process that when the initial contract creation is finished would then look in the directory for other files created between the time when the filewatcher was disabled and if there were none it would then re-enable the filewatcher but I am wondering if there is a simpler way to do this?
我认为另一个进程的初始合同创建完成后将在目录中寻找其他文件之间创建的时候filewatcher残疾,如果没有那么启用filewatcher但我想知道是否有更简单的方法?
2 个解决方案
#1
0
You could split your process in tasks. One task is the FileRegistrator , which picks up new files, registers them in database. It runs all the time, no need to EnableRaisingEvents to false.
您可以在任务中分割您的进程。一个任务是FileRegistrator,它获取新文件,在数据库中注册它们。它一直运行,不需要将事件变为错误。
The next task is the ProcessorTask (or whatever name) which will query the database, find the first one and processes it. It will query the database at regular times to see if a new file is registered.
下一个任务是ProcessorTask(或任何名称),它将查询数据库,找到第一个并处理它。它将定期查询数据库,以查看是否注册了新文件。
You could implement this little processor using Quartz.NET scheduler in a windows service.
您可以使用Quartz来实现这个小处理器。windows服务中的网络调度器。
(I did about the same a while ago, but I didn't use FileSystemWatcher)
(我以前也这么做过,但是我没有使用文件系统监视程序)
#2
0
A BlockingCollection would do this.
Keep FileWatcher hot and let it add to the blocking collection.
The consumer just processes the collection one at a time.
一个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);
}
}
}
}
#1
0
You could split your process in tasks. One task is the FileRegistrator , which picks up new files, registers them in database. It runs all the time, no need to EnableRaisingEvents to false.
您可以在任务中分割您的进程。一个任务是FileRegistrator,它获取新文件,在数据库中注册它们。它一直运行,不需要将事件变为错误。
The next task is the ProcessorTask (or whatever name) which will query the database, find the first one and processes it. It will query the database at regular times to see if a new file is registered.
下一个任务是ProcessorTask(或任何名称),它将查询数据库,找到第一个并处理它。它将定期查询数据库,以查看是否注册了新文件。
You could implement this little processor using Quartz.NET scheduler in a windows service.
您可以使用Quartz来实现这个小处理器。windows服务中的网络调度器。
(I did about the same a while ago, but I didn't use FileSystemWatcher)
(我以前也这么做过,但是我没有使用文件系统监视程序)
#2
0
A BlockingCollection would do this.
Keep FileWatcher hot and let it add to the blocking collection.
The consumer just processes the collection one at a time.
一个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);
}
}
}
}