【问题标题】:FileSystemWatcher on Threads线程上的 FileSystemWatcher
【发布时间】:2012-03-29 01:30:32
【问题描述】:

感谢您对此的任何帮助..

我正在尝试编写一个小的 FileWatcher 应用程序来监视本地目录并将任何更改复制到另一个本地目录。我在 .Net 中使用了 FileSystemWatcher 类,并在我的 btnStart 单击上运行四个线程,每个线程都有自己的 FileSysWatcher 实例,监视不同的更改类型。所以我首先要查找的是 created 事件。

new Thread(Created).Start();

那么我有:

void Created()
{
    FileSystemWatcher Watcher2 = new FileSystemWatcher();

    Watcher2.Path = txtBxDirToWatch.Text;
    Watcher2.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.DirectoryName;

    //watch all files in the path 

    Watcher2.Filter = "*.*";

    //dont watch sub dir as default
    Watcher2.IncludeSubdirectories = false;
    if (chkBxIncSub.Checked)
    {
        Watcher2.IncludeSubdirectories = true;
    }

    Watcher2.Created += new FileSystemEventHandler(OnCreated);
    Watcher2.EnableRaisingEvents = true;
}

我想要做的只是将任何更改复制到硬编码的本地路径,但我无法得到任何结果。这是我处理事件的地方

public static void OnCreated(object source, FileSystemEventArgs e)
{
    //combine new path into a string
    string created = Path.Combine(@"C:\WatcherChanges", e.Name);
    File.Create(created);
}

【问题讨论】:

  • 你试过调试它吗?你的 OnCreated 是否被击中然后你创建文件?您确定 e.Name 是文件名,而不是完整的文件路径吗?
  • 检查是否曾经创建过这个新线程,因为您正在从新线程访问 UI 控件。我相信它会引发异常,而您没有看到它。

标签: c# filesystemwatcher


【解决方案1】:

在你的代码线程完成然后GC收集并释放Watcher。

不要将线程用于观察者或“挂起”线程:

new Thread(Created){IsBackground = true}.Start(); 

void Created() 
{ 
  ...

  Thread.CurrentThread.Join();
} 

【讨论】:

    【解决方案2】:

    在您告诉观察者启用引发事件后,您的线程将立即退出。 Create 方法中没有任何内容可以保持线程运行。在Create 方法结束时,FileSystemWatcher 超出范围并且线程退出。它永远不会看到任何事件。

    有很多方法可以让线程等待。这是一个简单的。

    public class Watcher
    {
        private ManualResetEvent resetEvent = new ManualResetEvent(false);
    
        public ManualResetEvent ResetEvent { get { return resetEvent; }
    
        void Created()
        {
            FileSystemWatcher Watcher2 = new FileSystemWatcher();
    
            Watcher2.Path = txtBxDirToWatch.Text;
            Watcher2.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.DirectoryName;
    
            //watch all files in the path 
    
            Watcher2.Filter = "*.*";
    
            //dont watch sub dir as default
            Watcher2.IncludeSubdirectories = false;
            if (chkBxIncSub.Checked)
            {
                Watcher2.IncludeSubdirectories = true;
            }
    
            Watcher2.Created += new FileSystemEventHandler(OnCreated);
            Watcher2.EnableRaisingEvents = true;
    
            resetEvent.WaitOne();
        }
    

    然后把调用Thread.Start的方法改成类似

    Watcher watcher = new Watcher();
    new Thread(watcher.Created).Start();
    

    以及何时停止观看

    watcher.ResetEvent.Set();
    

    你看过RoboCopy吗?它会为你做到这一点。

    【讨论】:

      【解决方案3】:

      没有理由在单独的线程中创建观察者。

      当您监视的目录发生某些事情时,他们会在thread pool 线程上回复您。当他们这样做时 - 如果它与 UI 无关,您可以在线程池线程上完成您的工作。如果是 - 你必须做 control.Invoke 或使用 SynchronizationContext 发布/发送到 Gui 线程。

      是的——正如其他人已经说过的——不要让你的观察者被 GC'd。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多