我正在使用 Visual Studio 2012 制作一个 .dll,其中包含一个扩展 Windows 窗体 TreeView 窗体的类。我的自定义 TreeView 称为 FolderTreeView。在其中我添加了一些我需要的私有字段,主要是一个包含 DriveInfo 和关联的 FileSystemWatcher 的元组列表。
foreach(DriveInfo.GetDrives() 中的 var 驱动器) { if (drive.IsReady == true) { FileSystemWatcher watcher = new FileSystemWatcher(drive.RootDirectory.FullName); //_drives 是元组列表 _drives.Add(new Tuple<DriveInfo, FileSystemWatcher>(drive, watcher)); watcher.NotifyFilter = NotifyFilters.DirectoryName; watcher.IncludeSubdirectories = true; watcher.Created += new FileSystemEventHandler(FileSystemWatcher_OnCreated); watcher.Changed += new FileSystemEventHandler(FileSystemWatcher_OnChange); watcher.Deleted += new FileSystemEventHandler(FileSystemWatcher_OnDelete); watcher.Renamed += new RenamedEventHandler(FileSystemWatcher_OnRename); watcher.EnableRaisingEvents = true; Nodes.Add(drive.RootDirectory.Name); } }
这段代码会导致两个问题,我怀疑是偶数处理程序。第一个问题是 FileSystemWatcher 的事件是从不同的线程调用的,因此它会抛出异常,因为不应允许其他线程访问 Windows 窗体。
第二个问题是,如果我为 FileSystemWatcher 设置重命名事件处理程序的代码没有被注释掉,并且我在 Windows 资源管理器中更改了文件夹名称,Visual Studios 就会崩溃,我不知道为什么。我似乎很可能是由 Renamed 事件处理程序引起的。
我想先尝试解决线程问题,因为这可能会解决崩溃问题,除非有其他原因可能会发生这种情况。另外,在不同的类中处理所有文件系统的东西和节点构建,然后从所述类中获取一个节点并将其提供给常规 TreeView 会更好吗?
编辑:我确实相信它与线程有关。当它崩溃时,我可以在 Visual Studios 的另一个实例中进行调试,并且在我有断点的地方出现空引用异常。这让我有理由相信事件是在另一个线程中触发的,所以我的断点没有被它认为应该打开的线程击中?