C# 如何在不延迟处理的情况下处理大量filewatcher事件
为了处理大量的文件监视程序事件,我在我的文件监视程序中实现了以下代码 我已将一个文件夹复制到一个关注的位置。该文件夹中有大约40K个文件和文件夹。问题是队列项目没有立即得到处理。在一段时间内发生的处理。复制文件夹大约花了40分钟。但从文件复制开始,处理队列大约需要4-5个小时 我希望在复制文件夹后立即处理事件 以下是我的文件处理器类:C# 如何在不延迟处理的情况下处理大量filewatcher事件,c#,C#,为了处理大量的文件监视程序事件,我在我的文件监视程序中实现了以下代码 我已将一个文件夹复制到一个关注的位置。该文件夹中有大约40K个文件和文件夹。问题是队列项目没有立即得到处理。在一段时间内发生的处理。复制文件夹大约花了40分钟。但从文件复制开始,处理队列大约需要4-5个小时 我希望在复制文件夹后立即处理事件 以下是我的文件处理器类: class FileProcessor { private Queue<string> workQueue; private Thre
class FileProcessor
{
private Queue<string> workQueue;
private Thread workerThread;
private EventWaitHandle waitHandle;
public FileProcessor()
{
workQueue = new Queue<string>();
waitHandle = new AutoResetEvent(true);
}
public void QueueInput(string filepath)
{
workQueue.Enqueue(filepath);
// Initialize and start thread when first file is added
if (workerThread == null)
{
workerThread = new Thread(new ThreadStart(Work));
workerThread.Start();
}
// If thread is waiting then start it
else if (workerThread.ThreadState == ThreadState.WaitSleepJoin)
{
waitHandle.Set();
}
}
private void Work()
{
while (true)
{
string filepath = RetrieveFile();
if (filepath != null)
ProcessFile(filepath);
else
waitHandle.WaitOne();
}
}
private string RetrieveFile()
{
if (workQueue.Count > 0)
return workQueue.Dequeue();
else
return null;
}
private void ProcessFile(string filepath)
{
// Some processing done on the file
}
}
由于仍有一个线程处理
工作
函数,因此可能存在瓶颈。该线程只能以ProcessFile
能够通过队列的速度进行处理。如果ProcessFile
需要一段时间才能完成,则肯定会造成瓶颈
在您的例子中,您提到,ProcessFile
只是将事件发送到另一个应用程序。您应该检查应用程序是如何处理这些事件的。我猜它在返回之前正在执行这些事件的所有处理
您可能希望让您的其他应用程序将接收到的事件排队,以便它能够快速返回调用方。除此之外,您还需要研究如何使其以多线程方式处理这些事件,或者找到最大限度地提高这些事件处理效率的方法,否则您只需将瓶颈转移到新队列。您的文件处理器正在执行哪种处理?我认为这可能很大程度上决定了您的瓶颈。@jon-在ProcessFile方法中,我将向另一个应用程序发送文件创建事件。在返回到
ProcessFile
之前,另一个应用程序在做什么?如果它在返回之前进行了大量处理,您可能需要考虑使其他应用程序成为多线程应用程序。@jon,我的文件监视程序将使用管道向其他应用程序发送消息。另一个应用程序不是多线程的。但我的文件观察者并不期待任何响应,只是将消息发送到其他应用程序。我会尽力找出进程之间的瓶颈。@jon-你说得对,“其他”应用程序是单线程的。这就是问题所在。我想知道我怎样才能接受你的解决方案。
FileProcessor fileprocessor = new FileProcessor()
void onCreated(object source, FileSystemEventArgs e)
{
try
{
fileprocessor.QueueInput(e.FullPath);
}
catch (Exception ex)
{
}
}