我正在尝试制作一个程序来监视文件夹中的文件创建事件并对文件进行一些处理。我当前的实现使用:
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
fileSystemWatcher.Created += FileSystemWatcher_Created;
但是,这似乎有内存泄漏。每次FileSystemWatcher_Created
调用时,垃圾收集器在完成时不会处理它。我认为当原始对象仍然存在时,每个实例FileSystemWatcher_Created
都不能被处理掉。FileSystemWatcher
在这种情况下,我认为 using 对我没有fileSystemWatcher.Created -= FileSystemWatcher_Created;
帮助,因为我不想FileSystemWatcher_Created
只运行一次。我想FileSystemWatcher_Created
在每次文件创建事件发生时运行。我只希望垃圾收集器正确处理每个实例用完的内存。
我认为这意味着我想使用 aWeakEventHandler
来处理事件对吗?在这种情况下我该怎么做?我正在使用.NET Core
,但仍会感谢任何.NET Framework
答案。
编辑添加:FileSystemWatcher_Created
。我在检测到的文件上运行 PowerShell 脚本,然后在处理后移动它。
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
//Get FileInfo object for newly detected file
FileInfo file = new FileInfo(e.FullPath);
//Wait until the file is able to be accessed
while (IsFileLocked(file))
{
//If file is locked then wait 5 seconds and try again
Thread.Sleep(5000);
}
//Run PowerShell script from PowerShell_Script_Path with the operation, CSV filepath, and EXE filepath as arguments
ps.AddScript(File.ReadAllText(PowerShell_Script_Path)).AddArgument(GetOperation(e.Name)).AddArgument(e.FullPath).AddArgument(GetPath(Test_Mode)).Invoke();
//Wait until the file is able to be accessed
while (IsFileLocked(file))
{
//If file is locked then wait 10 seconds and try again
Thread.Sleep(10000);
}
//Move file from pending folder to archive folder
File.Move(e.FullPath, $"{Dst_Path}/{e.Name}", true);
}
经过一些试验和错误后,通过使用匿名函数订阅事件,我得到的内存泄漏最少。
//Set File Watch File Creation Event Handler
fileSystemWatcher.Created += (object sender, FileSystemEventArgs e) =>
{
//Get FileInfo object for newly detected file
FileInfo file = new FileInfo(e.FullPath);
//Wait until the file is able to be accessed
while (IsFileLocked(file))
{
//If file is locked then wait 5 seconds and try again
Thread.Sleep(5000);
}
//Run PowerShell script from PowerShell_Script_Path with the operation, CSV filepath, and EXE filepath as arguments
ps.AddScript(File.ReadAllText(PowerShell_Script_Path)).AddArgument(GetOperation(e.Name)).AddArgument(e.FullPath).AddArgument(GetPath(Test_Mode)).Invoke();
//Wait until the file is able to be accessed
while (IsFileLocked(file))
{
//If file is locked then wait 10 seconds and try again
Thread.Sleep(10000);
}
//Move file from pending folder to archive folder
File.Move(e.FullPath, $"{Dst_Path}/{e.Name}", true);
}