0

새 파일을 만들 때 SFTP 디렉토리에서 파일을 구문 분석 할 C# 콘솔 응용 프로그램을 만들어야합니다. 이를 위해 새 파일 경로를 대기열에 추가하고 새 스레드를 만들고 파일을 구문 분석하는 FileCreated 이벤트로 FileSystemWatcher를 구현했습니다.C# 콘솔 응용 프로그램에서 FileSystemWatcher와 Timer를 다중 스레드로 구현하는 방법은 무엇입니까?

필자는 FileSystemWatcher가 새로운 파일을 감지하지 못할 수도 있다는 블로그를 읽었습니다. 매주 1 시간마다 발생하는 Timer를 구현하고 FileSystemWatcher 스레드가 대기 상태에 있으면 IMCOMING SFTP 폴더를 읽고 구문 분석합니다 파일.

다음은 FileSystemWatcher 및 Timer 용으로 작성한 코드입니다.하지만 제대로 작동하지 않으며 filesystemwatcher가 다중 스레딩에 없다고 생각합니다. 올바른 해결책을 얻도록 도와주세요.

주요

static void Main(string[] args) 
    { 
     try 
     {     
      string path = incomingFilePath; 
      if (Directory.Exists(path)) 
      { 
       #region Initiate Timer 
       Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));      
       t.Start((Action)fileProcessor.StartTimer); 
       #endregion 

       #region FileSystemWatcher 
       watcher = new FileSystemWatcher { Path = path, Filter = "*.CUST", IncludeSubdirectories = true }; 
       watcher.Created += new 
       FileSystemEventHandler(watcher_FileCreated); 
       watcher.Error += new 
       ErrorEventHandler(watcher_OnError); 
       watcher.EnableRaisingEvents = true; 
       #endregion 
      } 
     } 
     catch (Exception Err) 
     { 

     } 
    } 

FileSystemWatcher 구성 CODE :

private static void watcher_FileCreated(object sender, FileSystemEventArgs e) 
    { 
     if (e.FullPath.ToUpper().Contains("INCOMING"].ToString())) 
     {        
      fileProcessor.EnqueueFile(e.FullPath); 
      lock (lockObject) 
      { 
       files.Enqueue(path); 
      } 

      if (FileWacherThread == null || shouldStop) 
      { 
       FileWacherThread = new Thread(new ThreadStart(Work));     
       FileWacherThread.Start(); 
      } 
      // If the thread is waiting then start it 
      else if (FileWacherThread.ThreadState == ThreadState.WaitSleepJoin) 
      {    
       waitHandle.Set(); 
      } 
     } 
    } 

    private void Work() 
    { 
     while (!shouldStop) 
     { 
      string path = String.Empty; 
      lock (lockObject) 
      { 
       if (files.Count > 0) 
       { 
        path = files.Dequeue(); 
       } 
      } 

      if (!String.IsNullOrEmpty(path)) 
      { 
       // Process the file      
       ParseFile(path); 
      } 
      else 
      { 
       // If no files are left to process then wait 
       waitHandle.WaitOne(); 
      } 
     } 
    } 

TIMER 코드

public void StartTimer() 
    { 
     lock (lockObject) 
     { 
      if (FileWacherThread == null || FileWacherThread.ThreadState == ThreadState.WaitSleepJoin) 
      { 
       if (files.Count == 0) 
       { 
        IEnumerable<string> result = new List<string>(Directory.GetFiles(incomingFilePath, "*.CUST", SearchOption.AllDirectories)).Where(s => s.Contains(incomingFilePrefix)); 
        foreach (string path in result) 
        { 
         ParseFile(path); 
        } 
       } 
      } 
     } 
    } 
+2

실제로 작동하지 않는 것은 무엇입니까? – fixagon

+0

btw, 고객 파일이 큰 경우 타이머 코드는 임시 파일을 먼저 작성하고 완료되면 * .CUST로 이름을 변경하지 않는 한 여전히 작성중인 파일을 찾을 수 있습니다. – mtijn

답변

0

것들 확인 ...

waitHandleAutoResetEvent 또는 ManualResetEvent? Work() 종료가 ...

가 어떻게 FileWacherThread에 대한 액세스를 보호 할 때 FileWacherThread (원문) null로 설정되는 AutoResetEvent

, shouldStoptrue 경우 (당신이 그것을 사용하는 방식에서, 그것은되어야 하는가? 여러 스레드에서 액세스 한 경우 (상태를 확인하고 할당 등) 잠금을 사용하여 보호해야합니다.

이벤트를 설정할 때 FileWacherThread의 상태에 대해 걱정할 필요가 없습니다. 그 스레드에 신호를 보내고 싶습니다. (즉, 멀티 스레드를 빌드하십시오. 발행자가 가입자의 현재 상태에 대해 알지 못함). 현재 귀하의 FileWacherThread이 대기하지 않을 수있는 상태가 있지만 신호가 필요할 수 있습니다. 항상 이벤트를 설정하면 최악의 상황은 불필요하게 한 번만 반복됩니다.