FileSystemWatcher для потоков - PullRequest
1 голос
/ 29 марта 2012

Спасибо за любую помощь в этом ..

Я пытаюсь написать небольшое приложение FileWatcher, которое отслеживает локальный каталог и копирует любые изменения в другой локальный каталог. Я использовал класс FileSystemWatcher в .Net, и на моем щелчке btnStart я запускаю четыре потока, каждый из которых имеет собственный экземпляр FileSysWatcher, отслеживая различные типы изменений. Поэтому первое, что я хочу найти, - это созданное событие.

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);
}

Ответы [ 3 ]

1 голос
/ 29 марта 2012

В вашем коде поток завершен, а затем GC собирает и выпускает Watcher.

Не использовать нить для наблюдателей или "зависать" нить:

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

void Created() 
{ 
  ...

  Thread.CurrentThread.Join();
} 
0 голосов
/ 29 марта 2012

Нет оснований для создания наблюдателей в отдельных потоках.

Они вернутся к вам в пуле потоков потоков, когда что-то произойдет в вашем наблюдаемом каталоге.Когда они это делают - вы выполняете свою работу в пуле потоков, если это не связано с пользовательским интерфейсом.Если это так - вы должны сделать control.Invoke или отправить / отправить в ветку Gui, используя SynchronizationContext .

И да - как уже сказали другие- не позволяйте своим наблюдателям получить GC'd.

0 голосов
/ 29 марта 2012

Ваш поток завершает работу сразу после того, как вы сообщаете наблюдателю, что нужно активировать события.В методе 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 ?Он сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...