停止 FileSystemWatcher 后运行另一段代码
Posted
技术标签:
【中文标题】停止 FileSystemWatcher 后运行另一段代码【英文标题】:Run another piece of code after stopping FileSystemWatcher 【发布时间】:2021-09-11 00:23:30 【问题描述】:我在 C# 中有一个FileSystemWatcher
代码,它检测已更改其内容的文件,然后将这些文件复制到指定目录(C:\Users\wost\Desktop\Data\files)。复制文件后,FileSystemWatcher
停止后,我想加密这些文件,我想在同一个程序中执行此操作。
所以我在主程序中有如下代码:
Watcher w = new Watcher(lexpt, fexpt, userName);
w.Watch();
// Function which encrypts the files
Encryption.EncryptFiles(@"C:\Users\wost\Desktop\Data\files");
这不起作用,因为FileSystemWatcher
永远不会停止,除非我退出程序。所以,我决定使用一个全局变量Global.serviceRunning
,如下面的代码所示,它会阻止FileSystemWatcher
在指定目录中观看:
public void Watch()
FileSystemWatcher watcher;
using (watcher = new FileSystemWatcher(
$"C:\\Users\\wost\\AppData\\Roaming\\Sublime Text 3", _ext))
// Watch for changes in LastAccess and LastWrite times, and
// the renaming of files or directories.
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
// Only watch text files.
// watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
// Add event handlers.
watcher.Changed += OnChanged;
watcher.Created += OnChanged;
watcher.Deleted += OnChanged;
watcher.Renamed += OnRenamed;
// Begin watching.
watcher.EnableRaisingEvents = true;
//GLOBAL VARIABLE
while (Global.serviceRunning == true) ;
我曾尝试在主程序中将此全局变量的值更改为false
,但它不起作用。你能帮我找到一种方法来停止FileSystemWatcher
,然后加密给定目录中的文件吗?
【问题讨论】:
“FileWatcher 永远不会停止,除非我退出程序” -- 嗯?为什么不直接将EnableRaisingEvents
设置回false
?或者,如果您不想在禁用 FileSystemWatcher
对象后再次使用它,只需调用其 Dispose()
方法即可。当然,像while (Global.serviceRunning == true) ;
这样的代码应该从不被使用;这将占用整个 CPU 内核而没有任何用处。但完全不清楚为什么您不只是使用记录在案的正常机制来控制FileSystemWatcher
对象。
@PeterDuniho 谢谢你的回答!这是我第一次使用 FileSystemWatcher,我不太了解它是如何工作的。
@PeterDuniho 你能告诉我我需要在哪里将 EnableRaisingEvents 设置为 false,是在主程序中还是在方法 Watch() 中?谢谢!
“我需要在哪里将 EnableRaisingEvents 设置为 false” - 您需要在执行代码时知道不再需要的地方设置它观察文件系统事件。您未能在帖子中解释您的场景的这一方面,因此无法将您指向代码中的确切位置。我怀疑它应该使用Watch()
方法。更有可能的是,在一个事件处理程序中,您知道您已经看到了您正在等待看到的任何内容,并且可以禁用 FileSystemWatcher
对象。
@PeterDuniho 我很抱歉。我以为很清楚。我不想在指定的时刻停止 FileSystemWatcher。我只是想在一段时间后停止它,这样我就可以给它足够的时间来寻找变化。我可以这样做吗?谢谢!
【参考方案1】:
您可以尝试取消相关事件以停止 FileSystemWatcher。
代码:
static void Stop()
watcher.EnableRaisingEvents = false;
watcher.Changed -=new FileSystemEventHandler(OnChanged);
watcher.Created -= new FileSystemEventHandler(OnChanged);
watcher.Deleted -= new FileSystemEventHandler(OnChanged);
watcher.Renamed -= new RenamedEventHandler(OnRenamed);
watcher.Dispose();
我在控制台应用中进行了测试。
完整代码:
class Program
static FileSystemWatcher watcher= new FileSystemWatcher();
public static void Main(string[] args)
watcher.Path = "E:\\Example";
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = "*.txt";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press\'q\' to stop the watcher.");
while (Console.ReadLine()=="q")
Stop();
;
Console.ReadKey();
static void Stop()
watcher.EnableRaisingEvents = false;
watcher.Changed -=new FileSystemEventHandler(OnChanged);
watcher.Created -= new FileSystemEventHandler(OnChanged);
watcher.Deleted -= new FileSystemEventHandler(OnChanged);
watcher.Renamed -= new RenamedEventHandler(OnRenamed);
watcher.Dispose();
public static void OnChanged(object sender, FileSystemEventArgs e)
Console.WriteLine("file:" + e.FullPath + "" + e.ChangeType);
public static void OnRenamed(object sender, RenamedEventArgs e)
Console.WriteLine("Fi]e:0 renamed to1", e.OldFullPath, e.FullPath);
【讨论】:
【参考方案2】:正如其他人指出的in the comments,FileSystemWatcher.EnableRaisingEvents
属性是您应该使用的机制,以便激活或停用FileSystemWatcher
组件对目标目录的监视。
请注意,尽管在 ThreadPool
上引发了 FileSystemWatcher
事件,但内部机制使得在停用组件后无法调用处理程序。但是,当您将EnableRaisingEvents
设置为false
时,任何已经运行的处理程序都不会被中止。因此,您应该考虑到,在监控停用之后,某些文件可能会在后台继续被复制。
【讨论】:
以上是关于停止 FileSystemWatcher 后运行另一段代码的主要内容,如果未能解决你的问题,请参考以下文章
FileSystemWatcher - 在删除时,复制一个文件
FileSystemWatcher 在功能后不会触发 [重复]