FileSystemWatcher导致桌面崩溃

时间:2012-01-06 18:55:51

标签: c# .net filesystemwatcher

我正在编写一个解决方案,我在其中使用一些应该在运行时可编辑的配置文件。我以前一直在使用FileSystemWatcher用于此目的,但从来没有遇到太多问题,但现在它导致了'重命名'事件的CTD。

这段(无用的)代码将在我的设置中重现问题:

private static int _s_renamed;
private static int _s_created;
private static int _s_errors;

private static void monitorConfiguration(string configRootFolder)
{
    var fsw = new FileSystemWatcher(configRootFolder, ConfigFilePattern)
    {
        NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName,
        IncludeSubdirectories = false
    };
    fsw.Renamed += (sender, args) => ++_s_renamed; // <-- ! CTD efter this one !
    fsw.Created += (sender, args) => ++_s_created;
    fsw.Error += (sender, args) => ++_s_errors; 
    fsw.EnableRaisingEvents = true;
}

崩溃来自FileSystemWatcher似乎。如果我在FileSystemWatcher.Renamed的事件处理程序中设置断点,它会被命中,但是当我退出它时应用程序崩溃了。如果我在FileSystemWatcher.Created事件处理程序中设置断点,则不会发生这种情况。

有什么建议吗?


编辑1: 我在Windows 7 x64(Ultimate)平台上运行.NET 4 我已经看过几个关于这类问题的讨论,但所有这些都与试图从事件处理程序更新UI内容(必须从主/ UI线程完成)的人有关。这就是我尝试在实验代码中增加一些计数器的原因。

4 个答案:

答案 0 :(得分:1)

只是为了澄清:

这里的问题是我的系统中其他地方有FileSystemWatcher的更多/更老的消费者,其中一个导致了未处理的异常。问题是异常被抛入一个完全不同的线程并导致应用程序崩溃到桌面。这个时间让我误以为这是我的新消费者以某种方式导致了这个问题,但是当我按照Chris Shain的建议(参见问题条目中的评论)来启用异常中断(msdn.microsoft.com/en-us/library/d14azbfh.aspx)时,我立即找到了真正的罪魁祸首。

我本来希望用解决方案来信任克里斯,但是他从来没有重新发布,所以在这里。希望我们学到了一些东西。

谢谢大家和快乐的编码

/纳斯

答案 1 :(得分:0)

您可能遇到这三种情况中的任何一种

  1. 传入的目录不存在,并且正在抛出未找到的文件。
  2. 传入的目录有效,但运行它的进程没有访问权限
  3. 传入的参数(sender,args),一个可能为null,您的代码(因为这是一个示例,我们看不到真正的代码)不处理null并抛出错误。

答案 2 :(得分:0)

在.NET中,您必须将FileSystemWatcher生成的线程与UI线程同步。为此,UI控件有一个方法,如:myControl.Invoke(...)为此效果。尝试同步的任何其他方式都会产生一些随机效果,如崩溃,异常等。

见这里: http://msdn.microsoft.com/en-us/magazine/cc300429.aspx http://weblogs.asp.net/justin_rogers/pages/126345.aspx

希望有所帮助

答案 3 :(得分:0)

也许您的文件或对象正在使用中,我遇到了类似的问题,我使用以下代码解决了这个问题

private void InitWatch()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\LoQueSea";
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
    | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.Filter = "*.*";
    watcher.Created += new FileSystemEventHandler(OnCreated);
    watcher.EnableRaisingEvents = true;
}
private void OnCreated()
{
    try
    {
        if (!myObjectToPrint.Dispatcher.CheckAccess())
        {
            myObjectToPrint.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                new Action(
                   delegate()
                   {
                    //your code here...
                   }
                   )
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }          
}

Saludos ..