2012-03-29 1 views
1

Merci pour toute aide sur ce ..FileSystemWatcher sur Threads

Je tente d'écrire une petite application qui surveille Filewatcher un répertoire local et des copies des changements vers un autre répertoire local. J'ai utilisé la classe FileSystemWatcher dans .Net et sur mon clic btnStart, j'exécute quatre threads, chacun avec sa propre instance FileSysWatcher, surveillant les différents types de changements. Donc le premier que je veux chercher est l'événement créé.

new Thread(Created).Start(); 

alors je dois:

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

tout ce que je veux que ce faire est de copier des modifications à un chemin d'accès local codé en dur mais je ne peux pas obtenir aucun résultat. voici où j'ai géré l'événement

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

Avez-vous essayé de le déboguer? Est-ce que votre OnCreated est frappé, alors vous créez un fichier? Êtes-vous sûr que e.Name est un nom de fichier, pas un chemin de fichier complet? – Nikolay

+1

Vérifiez si ce nouveau thread est jamais créé, Depuis que vous accédez aux contrôles de l'interface utilisateur à partir du nouveau thread. Je crois que c'est une exception et que vous ne le voyez pas. – Marcin

Répondre

0

Dans votre fil de code fini, puis GC recueillir et libérer Watcher.

Ne pas utiliser du fil pour les observateurs ou « accrocher » fil:

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

void Created() 
{ 
    ... 

    Thread.CurrentThread.Join(); 
} 
0

Votre fil est sortie juste après que vous dites le veilleur pour permettre des événements de collecte. Il n'y a rien dans la méthode Create pour garder le thread en cours d'exécution. À la fin de la méthode Create, le FileSystemWatcher est hors de portée et le thread se termine. Il ne verra jamais d'événements.

Il y a plusieurs façons d'attendre le thread. Voici un simple.

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

Ensuite, changez la méthode qui appelle Thread.Start à quelque chose comme

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

et quand vous voulez arrêter de regarder

watcher.ResetEvent.Set(); 

Avez-vous regardé RoboCopy? Il le fera pour vous.

0

Il n'y a aucune raison de créer les observateurs dans des fils séparés.

Ils reviendront à vous sur thread pool discussions quand quelque chose sur votre répertoire regardé se produit. Quand ils le font, vous faites votre travail sur le thread du pool de threads si ce n'est pas lié à l'interface utilisateur. Si c'est - vous devez faire control.Invoke ou poster/envoyer au fil de discussion en utilisant SynchronizationContext.

Et oui - comme les autres l'ont déjà dit - ne laissez pas vos observateurs obtenir GC'd.