3

Je développe un database file system. Il comprend un observateur multi-répertoire qui est un service Windows et qui utilise la classe file system watcher de .net.Comment affecter un thread séparé à chaque gestionnaire de système de fichiers?

Je souhaite exécuter chaque classe d'observateur sur un thread séparé. Thread ne peut pas être étendu dans .net car il est "Scellé". Ce que je veux, c'est exécuter toutes les méthodes de ma classe watcher dans le fil connexe. Comment puis-je y parvenir?

EDIT -

Ce qui suit est ma classe de veilleur de base.

public abstract class WatcherBase 
    { 
    private IWatchObject _watchObject; 

    public WatcherBase() { } 

    public WatcherBase(IWatchObject watchObject, bool canPauseAndContinue) 
    { 
     _watchObject = watchObject; 
     CanPauseAndContinue = canPauseAndContinue; 
    } 

    public bool CanPauseAndContinue { get; set; } 

    public IWatchObject ObjectToWatch 
    { 
     get 
     { 
      return _watchObject; 
     } 
    } 

    public abstract void Start(); 
    public abstract void Pause(); 
    public abstract void Continue(); 
    public abstract void Stop(); 
} 

Après est mon veilleur de répertoire classe étendue de la classe WatcherBase

namespace RankFs.WatcherService 
    { 
    public class DirectoryWatcher : WatcherBase 
    { 
    private WatchDirectory _directoryToWatch; 
    private FileSystemWatcher _watcher; 

    public DirectoryWatcher(WatchDirectory directory, bool CanPauseAndContinue) 
     :base(directory ,CanPauseAndContinue) 
    { 
     _directoryToWatch = directory; 
     _watcher = new FileSystemWatcher(_directoryToWatch.Path); 
     _watcher.IncludeSubdirectories = _directoryToWatch.WatchSubDirectories; 
     _watcher.Created +=new FileSystemEventHandler(Watcher_Created); 
     //_watcher.Changed +=new FileSystemEventHandler(Watcher_Changed); 
     _watcher.Deleted +=new FileSystemEventHandler(Watcher_Deleted); 
     _watcher.Renamed +=new RenamedEventHandler(Watcher_Renamed); 
    } 

    public WatchDirectory DirectoryToWatch 
    { 
     get 
     { 
      return _directoryToWatch; 
     } 
    } 

    public override void Start() 
    { 
     _watcher.EnableRaisingEvents = true; 
    } 

    public override void Pause() 
    { 
     _watcher.EnableRaisingEvents = false; 
    } 

    public override void Continue() 
    { 
     _watcher.EnableRaisingEvents = true; 
    } 

    public override void Stop() 
    { 
     _watcher.EnableRaisingEvents = false; 
    } 

    private void Watcher_Created(object sender, FileSystemEventArgs e) 
    { 
     // adds a new file entry to database 
    } 

    private void Watcher_Deleted(object sender, FileSystemEventArgs e) 
    { 
     //updates the database(deleted file) 
    } 

    private void Watcher_Renamed(object sender, RenamedEventArgs e) 
    { 
    //updates the database(renamed file) 
    } 
} } 

Je suis coincé à ce point.Please me aider.

Répondre

12

Le FileSystemWatcher déclenchera les événements dans un thread distinct. La logique à l'intérieur des gestionnaires d'événements devra tenir compte de ce fait et effectuer toute synchronisation nécessaire.

Si vous exécutez l'exemple suivant, vous verrez que le gestionnaire d'événements Changed s'exécutera dans un thread différent.

public static void Main(string[] args) 
{ 
    Directory.CreateDirectory("dir1"); 
    Directory.CreateDirectory("dir2"); 
    Directory.CreateDirectory("dir3"); 

    Console.WriteLine("Main Thread Id: {0}", 
     Thread.CurrentThread.ManagedThreadId); 

    const int watcherCount = 3; 
    string[] dirs = new string[] { "dir1", "dir2", "dir3" }; 

    for (int i = 0; i < watcherCount; i++) 
    { 
     var watcher = new FileSystemWatcher(); 
     watcher.Path = dirs[i]; 
     watcher.Changed += (sender, e) => 
     { 
      Console.WriteLine("File: {0} | Thread: {1}", e.Name, 
       Thread.CurrentThread.ManagedThreadId); 

      Thread.Sleep(2000); // Simulate long operation 
     }; 
     watcher.EnableRaisingEvents = true; 
    } 

    File.WriteAllText(@"dir1\test1", "hello"); 
    File.WriteAllText(@"dir2\test2", "hello"); 
    File.WriteAllText(@"dir3\test3", "hello"); 

    Thread.Sleep(10000); 
} 

Lors de l'exécution de cet échantillon I obtenu la sortie suivante:

// Main Thread Id: 1 
// File: test1 | Thread: 3 
// File: test2 | Thread: 4 
// File: test3 | Thread: 5 
// File: test1 | Thread: 3 
// File: test2 | Thread: 4 
// File: test3 | Thread: 5 

MISE À JOUR: Puisque vous utilisez l'approche des événements dans le FileSystemWatcher vous utilisez déjà une approche multithread parce que les gestionnaires d'événements pour chaque instance FileSystemWatcher sera déclenché dans un thread séparé d'une manière asynchrone.

+0

Je ne pouvais pas avoir une idée sur la façon de réaliser le multi threading. Pourriez-vous nous aider davantage? J'ai modifié ma question et fourni le code comme référence. Jetez un coup d'oeil. –

+0

@Ravi Vous n'avez rien d'autre à faire pour que vos méthodes de gestionnaire d'événements s'exécutent sur un thread séparé. – SpaceghostAli

+0

C'est la sortie que j'ai obtenue. 'Numéro de fil principal 12 Test de fichier Filetage 13 Test de fichier Filetage 13' Toujours pas de multithreading.Pourquoi? –

0

Je voudrais écrire une nouvelle classe que wraps or adapts FileSystemWatcher, puis lancer ma nouvelle classe sur un nouveau thread. La classe d'adaptateur gérera les notifications de la classe FSW, et vous pourrez alors trouver le meilleur moyen de diffuser ou de relayer ces notifications vers une sorte de fonction de marshalling.

Il existe plusieurs façons de lancer de nouveaux threads et des milliards de tutoriels sur la façon de le faire, donc je ne vais pas le couvrir ici dans cette réponse.

+0

J'ai déjà fait le truc "wrapping". Et vous dites "lancer une nouvelle classe sur un nouveau fil" .Mon question est la même.Comment faire? Je suis coincé. –

Questions connexes