在.NET C#中是否有其他的FileSystemWatcher替代方案?

在.NET C#中是否有其他的FileSystemWatcher替代方案?,c#,file-watcher,C#,File Watcher,我是.NETCore的新手,目前正在处理一个需要处理目录中文件的用例 应用程序正在使用FileSystemWatcher类监视目录。 下面是我用来监视目录的代码 private FileSystemWatcher watcher = new FileSystemWatcher(); private List<CustomFileEvent> custEventsList = new List(); private void MonitorDirectory(strinig dir

我是.NETCore的新手,目前正在处理一个需要处理目录中文件的用例

应用程序正在使用
FileSystemWatcher
类监视目录。
下面是我用来监视目录的代码


private FileSystemWatcher watcher = new FileSystemWatcher();
private List<CustomFileEvent> custEventsList = new List();

private void MonitorDirectory(strinig dirName) 
{
    
    watcher.Path = dirName;
    watcher.IncludeSubdirectories = true;
    
    watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
    
    watcher.Filter = "*.*";
    
    // Add created event handler
    watcher.Created += new FileSystemEventHandler(OnChanged);
    //
    //watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    // Setting the internal buffer size to 24kb. By default it is 8kb
    watcher.InternalBufferSize = 24000;

    // Begin watching.
    watcher.EnableRaisingEvents = true;
    
    watcher.WaitForChanged(WatcherChangeTypes.All);
}

private void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine("Event Occured");
    Console.WriteLine($"File: {e.FullPath} {e.ChangeType}");
    
    // Code to handle the file created event
    // Passing the parameters fileName, fullPath, dateTime, and size of the file
    CreateFileEvent(......)
    
}

private void CreateFileEvent(string fileName, string fullPath, DateTime timeStamp,long size) {
    // Code to create the File created event
    var customFileEvent = new CustomFileEvent()
    {
        FileName = fileName,
        FullPath = fullPath,
        TimeStamp = timeStamp,
        Size = size
    };
    
    custEventsList.Add(customFileEvent);
}

private void TimerFunction(object sender, ElapsedEventArgs e)
{
    if (custEventsList != null && custEventsList.Count != 0)
    {
        Console.WriteLine("Total events :: " + custEventsList .Count);

        foreach (var evnt in custEventsList)
        {
            ProcessEvent( ..... arguments to send the file watcher events);
        }
    }
    
    // Clear your file List.
    custEventsList = new List<CustomFileEvent>();  // CustomFileEvent is a custom class
}

private FileSystemWatcher watcher=new FileSystemWatcher();
私有列表custEventsList=新列表();
专用void监视器目录(strinig dirName)
{
watcher.Path=dirName;
watcher.IncludeSubdirectories=true;
watcher.NotifyFilter=NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
watcher.Filter=“***”;
//添加已创建的事件处理程序
watcher.Created+=新文件系统EventHandler(OnChanged);
//
//watcher.Deleted+=新文件系统EventHandler(一旦更改);
watcher.Renamed+=新重命名的EventHandler(OnRenamed);
//将内部缓冲区大小设置为24kb。默认情况下为8kb
watcher.InternalBufferSize=24000;
//开始观看。
watcher.EnableRaisingEvents=true;
WaitForChanged(WatcherChangeTypes.All);
}
私有void OnChanged(对象源、文件系统目标)
{
Console.WriteLine(“发生事件”);
WriteLine($“文件:{e.FullPath}{e.ChangeType}”);
//处理文件创建事件的代码
//传递文件名、完整路径、日期时间和文件大小的参数
CreateFileEvent(……)
}
私有void CreateFileEvent(字符串文件名、字符串完整路径、日期时间戳、长大小){
//用于创建文件创建事件的代码
var customFileEvent=new customFileEvent()
{
FileName=FileName,
完整路径=完整路径,
时间戳=时间戳,
大小=大小
};
custEventsList.Add(customFileEvent);
}
私有void timer函数(对象发送器,ElapsedEventArgs e)
{
if(custEventsList!=null&&custEventsList.Count!=0)
{
WriteLine(“总事件::”+custEventsList.Count);
foreach(custEventsList中的var evnt)
{
ProcessEvent(..…用于发送文件监视程序事件的参数);
}
}
//清除您的文件列表。
custEventsList=new List();//CustomFileEvent是一个自定义类
}
假设应用程序正在监视文件夹C:\MyAppFiles\AppEvents
创建TimerFunction是为了在每20秒间隔后处理事件。
ProcessEvent
方法实际上用于将文件详细信息发送到另一个Windows服务,该服务处理该文件并将其删除

有了这段代码,我可以一次成功地处理一个文件并将其删除。当我尝试使用以下步骤处理多个文件时,就会出现问题

  • 将FileData.txt复制到监视文件夹。发生创建的
    事件,并调用OnChanged函数
  • CreateFileEvent
    创建自定义事件
  • TimerFunction每20秒处理一次事件
  • 在20秒之前复制FileData_2.txt
  • 该文件夹有2个文件要处理
  • 代码同时处理文件和删除文件。文件夹现在是空的
  • 现在我放置了另一个文件FileData_3.txt
  • 发现未生成创建的
    事件。并且该文件未得到处理
  • 更新:我注意到在ProcessEvent函数中处理完文件后,FileSystemWatcher会自动被释放。只有当我试图放置多个文件进行处理时,才会发生这种情况。对于单个文件,它可以成功地工作


    请给出建议。

    我不知道这是否是一个完整的解决方案,但您对该代码有一个大问题:

    • FileSystemWatcher变量在foreach循环中的每次迭代后都会被销毁
    这是一个问题,因为您不知道对象是否仍在某个位置被引用。您创建的所有FileSystemWatcher都应该保存在一个数组或类似的东西中,该数组或类似的东西在调用您的方法后不会被销毁(即作为实例变量)

    由于您没有显示实际处理事件的代码,因此很难确切地说出问题的根源。但是请记住,如果您的线程卡在OnChanged方法中,在您正确离开该方法之前,不会触发其他事件

    请共享方法
    CreateFileEvent
    TimerFunction
    的代码

    编辑:

    您可能希望查看.Net类,因为您有多个线程在操作列表,并且不注意线程安全


    另外,您不必调用WaitForChanged,在方法结束时,将EnableRaisingEvent设置为true就足够了。

    最后,我能够解决这个问题。 使用了
    ManualResetEvent ManualResetEvent=新的ManualResetEvent(错误)作为成员变量和
    manualResetEvent.WaitOne()编码到函数中

    下面是代码

    private FileSystemWatcher watcher = new FileSystemWatcher();
    private List<CustomFileEvent> custEventsList = new List();
    
    private readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false);
    
    private void MonitorDirectory(strinig dirName) 
    {
        
        watcher.Path = dirName;
        watcher.IncludeSubdirectories = true;
        
        watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
        
        watcher.Filter = "*.*";
        
        // Add created event handler
        watcher.Created += new FileSystemEventHandler(OnChanged);
        //
        //watcher.Deleted += new FileSystemEventHandler(OnChanged);
        watcher.Renamed += new RenamedEventHandler(OnRenamed);
    
        // Setting the internal buffer size to 24kb. By default it is 8kb
        watcher.InternalBufferSize = 24000;
    
        // Begin watching.
        watcher.EnableRaisingEvents = true;
        
        // watcher.WaitForChanged(WatcherChangeTypes.All);
        manualResetEvent.WaitOne();
    }
    
    private FileSystemWatcher watcher=new FileSystemWatcher();
    私有列表custEventsList=新列表();
    专用只读手动复位事件手动复位事件=新手动复位事件(假);
    专用void监视器目录(strinig dirName)
    {
    watcher.Path=dirName;
    watcher.IncludeSubdirectories=true;
    watcher.NotifyFilter=NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;
    watcher.Filter=“***”;
    //添加已创建的事件处理程序
    watcher.Created+=新文件系统EventHandler(OnChanged);
    //
    //watcher.Deleted+=新文件系统EventHandler(一旦更改);
    watcher.Renamed+=新重命名的EventHandler(OnRenamed);
    //将内部缓冲区大小设置为24kb。默认情况下为8kb
    watcher.InternalBufferSize=24000;
    //开始watc