3

나는 database file system을 개발 중이다. 이것은 Windows 서비스이고 .net의 file system watcher 클래스를 사용하는 다중 디렉토리 감시자를 포함하고있다.각 파일 시스템 감시자에 별도의 스레드를 할당하는 방법은 무엇입니까?

별도의 스레드에서 각 감시자 클래스를 실행하고 싶습니다. 스레드는 "봉인되어"있기 때문에 .net에서 확장 할 수 없습니다. 내가 원하는 것은 관련된 스레드에서 Watcher 클래스의 모든 메서드를 실행하는 것입니다. 어떻게해야합니까? 편집

-

다음은 내 기본 감시자 클래스입니다. 다음

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

이 point.Please에서 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) 
    } 
} } 

내가 끼 었어에서 확장 내 디렉토리 감시자 클래스 도와입니다.

답변

12

FileSystemWatcher은 별도의 스레드에서 이벤트를 트리거합니다. 이벤트 처리기 내부의 논리는이 사실을 고려하여 필요한 모든 동기화를 수행해야합니다.

다음 예제를 실행하면 Changed 이벤트 처리기가 다른 스레드에서 실행되는 것을 확인할 수 있습니다. 이 샘플을 실행하는 경우

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

나는 다음과 같은 출력을 얻을 :

// 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 

UPDATE : 당신은 이미 이벤트 핸들러 때문에 멀티 스레드 방식을 사용하는 FileSystemWatcher의 이벤트 접근 방식을 사용하고 있기 때문에 각 FileSystemWatcher 인스턴스는 비동기 방식으로 별도의 스레드에서 트리거됩니다.

+0

멀티 스레딩을 달성하는 방법에 대한 아이디어가 없습니다. 더 많은 도움을 주시기 바랍니다. 내 질문을 편집하고 참조 용 코드를 제공했습니다. 한번보세요. –

+0

@Ravi 별도의 스레드에서 이벤트 처리기 메서드를 실행하기 위해 다른 작업을 수행 할 필요가 없습니다. – SpaceghostAli

+0

이것은 제가 얻은 결과입니다. '주요 스레드 ID 12 파일 테스트 스레드 13 파일 테스트 스레드 13' 여전히 멀티 스레딩 없음. 왜 그렇습니까? –

0

wraps or adapts FileSystemWatcher라는 새 클래스를 작성한 다음 새 스레드에서 새 클래스를 시작할 수 있습니다. 어댑터 클래스는 FSW 클래스의 알림을 처리하기 때문에 일종의 마샬링 함수로 알림을 브로드 캐스트하거나 릴레이하는 가장 좋은 방법을 찾을 수 있습니다.

새 스레드를 시작하는 방법과 수십억 개의 자습서를 시작하는 방법이 몇 가지 있습니다.이 답변에서 다루지 않을 것입니다.

+0

나는 이미 "감싸는"일을 끝냈습니다. 그리고 당신은 "새로운 수업에 새로운 수업 시작"이라고 말하고 있습니다. 제 질문은 동일합니다. 어떻게해야합니까? 나는 붙어있다. –

관련 문제