C# .net自定义表单甚至处理程序从不同线程调用并崩溃

C# .net自定义表单甚至处理程序从不同线程调用并崩溃,c#,winforms,visual-studio,crash,treeview,C#,Winforms,Visual Studio,Crash,Treeview,我正在使用Visual Studio 2012创建一个.dll,其中包含一个扩展Windows窗体树视图窗体的类。我的自定义树视图称为FolderTreeView。在它里面,我添加了一些我需要的私有字段,主要是一个元组列表,其中包含一个DriveInfo和一个相关的FileSystemWatcher foreach (var drive in DriveInfo.GetDrives()) { if (drive.IsReady == tru

我正在使用Visual Studio 2012创建一个.dll,其中包含一个扩展Windows窗体树视图窗体的类。我的自定义树视图称为FolderTreeView。在它里面,我添加了一些我需要的私有字段,主要是一个元组列表,其中包含一个DriveInfo和一个相关的FileSystemWatcher

foreach (var drive in DriveInfo.GetDrives()) { if (drive.IsReady == true) { FileSystemWatcher watcher = new FileSystemWatcher(drive.RootDirectory.FullName); //_drives is List of Tuples _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); } } foreach(DriveInfo.GetDrives()中的var驱动器) { 如果(drive.IsReady==true) { FileSystemWatcher-watcher=新的FileSystemWatcher(drive.RootDirectory.FullName); //_驱动器是元组列表 _添加(新元组<DriveInfo,FileSystemWatcher>(驱动器,watcher)); watcher.NotifyFilter=NotifyFilters.DirectoryName; watcher.IncludeSubdirectories=true; watcher.Created+=新的FileSystemEventHandler(FileSystemWatcher\u OnCreated); watcher.Changed+=新的FileSystemEventHandler(FileSystemWatcher\u OnChange); watcher.Deleted+=新的FileSystemEventHandler(FileSystemWatcher\u OnDelete); watcher.rename+=new-RenamedEventHandler(FileSystemWatcher\u OnRename); watcher.EnableRaisingEvents=true; 添加(drive.RootDirectory.Name); } } 这段代码会导致两个问题,我怀疑这两个问题都与偶数处理程序有关。第一个问题是FileSystemWatcher的事件是从另一个线程调用的,因此它会引发异常,因为不应允许其他线程访问Windows窗体

第二个问题是,如果我为FileSystemWatcher设置重命名事件处理程序的代码没有被注释掉,并且我在Windows资源管理器中更改了文件夹名称,Visual Studio就会崩溃,我不知道为什么。我觉得这很可能是由重命名的事件处理程序引起的

我想先帮助解决线程问题,因为这可能会解决崩溃问题,除非有其他原因。另外,在不同的类中处理所有文件系统内容和节点构建是否更好,只需从所述类中获取一个节点并将其交给常规的树视图


编辑:我相信这与线程有关。当它崩溃时,我可以在另一个VisualStudio实例中进行调试,在我有断点的地方出现空引用异常。这使我有理由相信事件是在另一个线程中触发的,因此我的断点不会被它认为应该打开的线程击中?

在事件处理程序中,如果要操作Windows窗体控件,则需要检查
窗体/控件。invokererequired
,请参阅:

如果这是真的,那么您是从与UI线程不同的线程调用的。在这种情况下,请使用
Form/Control.Invoke
将事件排入UI线程队列,请参阅:


另请参见:

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

这是正常的,这些事件是在线程池线程上引发的。导入,因为需要快速处理事件以避免缓冲区溢出。当您监听每个驱动器上每一个可能的文件更改时,您确实需要这样做。非常不明智的做法是,您甚至无法调用Control.BeginInvoke()来避免异常。ConcurrentQueue是最低要求。@HansPassant是否最好为树视图中的每个扩展节点构造一个新的FileSystemWatcher,并将IncludeSubDirectories设置为false,只监视可见节点?此外,我只监视目录,如果这有助于解决大缓冲区问题?