2012-03-20 1 views
0

로이 코드 노력하고 있습니다 잘 :멀티 스레딩 FileSystemWatching

Creating plugin for file c:\temp\file1.txt 
Creating plugin for file c:\temp\file2.txt 
Creating plugin for file c:\temp\file3.txt 
Starting watching c:\temp\file1.txt 
Finished watching file c:\temp\file1.txt 
Starting watching c:\temp\file2.txt 
Finished watching file c:\temp\file2.txt 
Starting watching c:\temp\file3.txt 
Finished watching file c:\temp\file3.txt 
: 코드에서 인쇄

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Threading; 

namespace Test2 
{ 
    internal static class MyProgram 
    { 
     [STAThread] 
     private static void Main(string[] args) 
     { 
      List<Plugin> plugins = new List<Plugin> 
             { 
              new Plugin(@"c:\temp\file1.txt"), 
              new Plugin(@"c:\temp\file2.txt"), 
              new Plugin(@"c:\temp\file3.txt"), 
             }; 

      foreach (var plugin in plugins) 
      { 
       plugin.StartWatch(); 
       plugin.WaitHandler.WaitOne(); 
      } 
     } 
    } 


    public class Plugin 
    { 
     private FileSystemWatcher _watcher; 
     private readonly string _file; 
     public AutoResetEvent WaitHandler { get; private set; } 

     public Plugin(string file) 
     { 
      _file = file; 
      Console.WriteLine("Creating plugin for file {0}", _file); 
      WaitHandler = new AutoResetEvent(false); 
     } 

     public void StartWatch() 
     { 
      Console.WriteLine("Starting watching {0}", _file); 
      WaitHandler.Reset(); 
      FileInfo fileInfo = new FileInfo(_file); 
      if (fileInfo.Directory != null) 
      { 
       _watcher = new FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name); 
       _watcher.NotifyFilter = NotifyFilters.LastWrite; 
       _watcher.Changed += OnChanged; 
       _watcher.EnableRaisingEvents = true; 
      } 
     } 

     private void OnChanged(object source, FileSystemEventArgs e) 
     { 
      Console.WriteLine("Finished watching file {0}", _file); 
      _watcher.Dispose(); 
      WaitHandler.Set(); 
     } 
    } 
} 

결과는 (제대로 작동하고 중요되는) 다음이다

내가 가진 문제는 내 프로그램을 멀티 스레드로 만들고 다른 스레드가 백그라운드에서 실행되도록하려는 것입니다. 주 스레드가 AutoResetEvent에 의해 차단되기 때문에이 디자인으로는 작업을 수행 할 수 없습니다. 내가 추가하고 싶은 다른 스레드는 "AbortFlagFile.txt"라는 파일을 수신하는 스레드입니다. 한 번 "AbortFlagFile.txt"수정보다 내 프로그램을 중단해야합니다. OnChange()가 끝난 후 해고 될 PluginEndEvent를 생성하려고 생각했습니다.

내가 쓴 것과 같은 순서로 로그를 생성한다는 것은 매우 중요합니다. 감사합니다!

답변

0

waithandles = new WaitHandle[3] { new AutoResetEvent(false), new AutoResetEvent(false) }; 

또한 스레드 카운터를 증가시키는 기능을 필요 초기화 waithandles들의 어레이 및 이의 생성자에서

private static WaitHandle[] waithandles; 
private static int waitcount; 

선언

private static void incThreadCounter() 
{ 
     lock (sobj) 
    { 
    waitcount++; 
    } 
} 

에서 스레드를 초기화하는 코드는 incThreadCounter()를 호출하십시오.

스레드가 스풀링 된 후 실제로 콜백으로 처리합니다. , 당신은 다음 부분, 거짓 카운트 당신이 당신의 자동 리셋이 while 루프를 설정하고, 카운트가 0 인 경우가

while (waitcount > 0) 
{ 
    WaitHandle.WaitAny(waithandles, 5000); 
    waitcount--; 
} 

신호로 스레드 수 을 감소 지역에

을 진행 방지하는 추가 스레드를 스풀링하고있을 수 있습니다.

스레드 1이 스레드 2 이후에 실행되도록하려면 위의 논리 변형을 사용하는 것이 좋습니다. 사실 스레드 2가 항상 스레드 1 이후에 실행되어야하고 스레드 3이 스레드 2 이후에 항상 실행되어야한다면 실제로는 멀티 스레딩이 필요하지 않습니다. 스레딩은 동시에 실행할 수있는 프로세스가있는 경우에만 유용합니다.

희망이 도움이되었습니다.