0

我正在使用 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 的另一个实例中进行调试,并且在我有断点的地方出现空引用异常。这让我有理由相信事件是在另一个线程中触发的,所以我的断点没有被它认为应该打开的线程击中?

4

2 回答 2

1

在您的事件处理程序中,如果您想操作 Windows 窗体控件,您将需要检查Form/Control.InvokeRequired,请参阅:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired。 aspx

如果这是真的,那么你是从与 UI 线程不同的线程调用的。在这种情况下,使用Form/Control.Invoke在 UI 线程上排队的事件,请参阅:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke.aspx

另请参阅:http: //msdn.microsoft.com/en-us/library/ms171728 (v=vs.85).aspx

于 2013-10-12T10:59:52.013 回答
0

InvokeRequired 似乎运作良好,但我最近找到了另一种方法。FileSystemWatcher 有一个名为 SynchronizingObject 的属性。如果将其设置为 FolderTreeView,或者this由于它在继承表单的类中,问题似乎也得到了解决。

于 2013-10-14T03:14:41.087 回答