[英]Program design issue , filesystemwatcher, multithreading c#
我正在开发ac#程序,它使用FilesystemWatcher来监视添加到monitor_directory中的PDF文件。 每次将文件添加到目录时,我都会将其添加到另一个线程无限循环中连续弹出的BlockingQueue,它会等待添加文件路径,之后我继续处理文件,最后一部分PDF文件处理正在将其移动到输出目录。
调度线程:
private static void ThreadProc(object param)
{
FileMonitorManager _this = (FileMonitorManager)param;
FileProcessingManager processingManager = new FileProcessingManager();
processingManager.RegisterProcessor(new ExcelFileProcessor());
processingManager.RegisterProcessor(new PdfFileProcessor());
while (true)
{
try
{
var path = (string)_this.FileQueue.Dequeue();
if (path == null)
break;
bool b = processingManager.Process(path);
if (!b)
{
_this.FileQueue.Enqueue(path);
Console.WriteLine("\n\nError on file: " + path);
}
else
Console.WriteLine("\n\nSucces on file: " + path);
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
}
Process函数测试文件是否存在,进行一些处理并将PDF文件移动到输出目录。
我遇到了两个问题:1。来自FileSystemWatcher的On_Create事件处理程序被触发TWICE,因此BlockingQueue具有相同的两次条目,在这种情况下,在处理例程中我验证文件是否尚未移动到输出目录(因为这是处理的最后部分包括在那里移动文件),如果是这样我继续进行处理,如果没有我退出。 2.如果由于某种原因我得到一个错误,访问文件的内容说:该文件正由另一个进程使用我从Process函数返回FALSE并再次将文件路径添加到队列。
现在..这有效,但它有点慢..我怎么能通过考虑我面临的两个问题来做多线程.. 编辑:如果我得到事件,将其添加到队列,它被弹出,队列是空的然后我再次获得相同的事件,队列是空的,所以它被添加,基本上我得到相同的事件处理TWICE?
众所周知,FileSystemWatcher很健谈。
我想这就是我要做的......
执行此多线程的一种简单方法是每次出列路径时启动一个新任务...
Task.Factory.StartNew(() =>
{
try
{
var path = (string) _this.FileQueue.Dequeue();
if (path == null)
break;
bool b = processingManager.Process(path);
if (!b)
{
_this.FileQueue.Enqueue(path);
Console.WriteLine("\n\nError on file: " + path);
}
else
Console.WriteLine("\n\nSucces on file: " + path);
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
});
对于生产代码,您还需要将取消令牌传递给任务,并具有停止循环和任务的机制。
1) FileSystemWatcher通知您两次,因为文件分两步更新:首先是数据 ,然后是元数据 。 因此,您可以使用以下内容检查最新的写入是否已被考虑在内:
File.GetLastWriteTime(file);
或者您可以检查重复项。
2)你没有使用多线程:你一次处理一个文件,所以你可以产生一些线程来执行Process方法,例如使用:
ThreadPool.QueueUserWorkItem
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.