2014-03-06 1 views
2

여기 지침을 따르고 있습니다 FileSystemWatcher Changed event is raised twice.파일 목록에 대한 FileSystemwatcher

그러나 20 개의 파일을 함께 삭제하면 20 개의 파일이 삭제되므로보고있는 파일 목록이 있습니다. 이것은 예상과 잘 작동합니다.

20 동시 "파일 변경 (예 : Onchanged 첫 번째 인스턴스의 코드가 완료 될 때까지 다른 모든 파일 변경 사항을 무시할 수있는 한 번만 이벤트를 발생시킬 수 있습니다.) 지금 Onchanged 20 번 호출됩니다. .)?

private void Main_Load(object sender, EventArgs e) 
{ 
    public static List<FileSystemWatcher> watchers = new List<FileSystemWatcher>(); 
    UpdateWatcher(); 
} 


public void OnChanged(object sender, FileSystemEventArgs e) 
{ 
    try 
    { 
     Logging.Write_To_Log_File("Item change detected " + e.ChangeType + " " + e.FullPath + " " + e.Name, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2); 
     watchers.Clear(); 

     foreach (FileSystemWatcher element in MyGlobals.watchers) 
     { 
     element.EnableRaisingEvents = false; 
     } 

     //Do some processing on my list of files here.... 
     return; 

    }  
    catch (Exception ex) 
    { 
     // If exception happens, it will be returned here 
    }     
    finally 
    { 
     foreach (FileSystemWatcher element in MyGlobals.watchers) 
     { 
      element.EnableRaisingEvents = true; 
     } 
    } 
} 





public void UpdateWatcher() // Check Items 
     { 

     try 
     { 
     watchers.Clear(); 

     for (int i = 0; i < MyGlobals.ListOfItemsToControl.Count; i++) // Loop through List with for 
     { 
     FileSystemWatcher w = new FileSystemWatcher(); 
     w.Path = Path.GetDirectoryName(MyGlobals.ListOfItemsToControl[i].sItemName); // File path  
     w.Filter = Path.GetFileName(MyGlobals.ListOfItemsToControl[i].sItemName); // File name 
     w.Changed += new FileSystemEventHandler(OnChanged); 
     w.Deleted += new FileSystemEventHandler(OnChanged); 
     w.Created += new FileSystemEventHandler(OnChanged); 
     w.EnableRaisingEvents = true; 
     watchers.Add(w); 
     } 
     } 
     catch (Exception ex) 
     { 
     // If exception happens, it will be returned here 

     } 
     } 

답변

1

여기서 중요한 점은 "함께"의미하는 것입니다. 모든 시스템이 각각에 대해 독립적 인 삭제 작업을 수행 한 후에 기술적으로 완전히 동일한 시간에 모두 삭제되지는 않는다는 것을 의미합니다. 다만 닫기를 원할 경우 서로 5 초 이내에 모두 삭제 된 경우 OnChange가 한 번만 발사되도록하려면 다음을 수행 할 수 있습니다. 이것은 이름 변경 알림을 처리하지 않습니다. 너는 그 말을 듣지 않았으므로 나는 네가 그렇게 할 필요가 없다고 생각했다.

사용에 따라 5 초 창을 작은 창으로 변경하고 싶을 수 있습니다.

class SlowFileSystemWatcher : FileSystemWatcher 
    { 
     public delegate void SlowFileSystemWatcherEventHandler(object sender, FileSystemEventArgs args); 

     public event SlowFileSystemWatcherEventHandler SlowChanged; 
     public DateTime LastFired { get; private set; } 

     public SlowFileSystemWatcher(string path) 
      : base(path) 
     { 
      Changed += HandleChange; 
      Created += HandleChange; 
      Deleted += HandleChange; 
      LastFired = DateTime.MinValue; 
     } 

     private void SlowGeneralChange(object sender, FileSystemEventArgs args) 
     { 
      if (LastFired.Add(TimeSpan.FromSeconds(5)) < DateTime.UtcNow) 
      { 
       SlowChanged.Invoke(sender, args); 
       LastFired = DateTime.UtcNow; 
      } 
     } 

     private void HandleChange(object sender, FileSystemEventArgs args) 
     { 
      SlowGeneralChange(sender, args); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      SlowChanged = null; 
      base.Dispose(disposing); 
     } 
    } 
+0

파일 시스템 감시자가이 코드보다 앞에있는 것처럼 보입니다. lastfired 값을 업데이트 할 수있을 때까지 이벤트는 이미 40 개의 파일을 삭제할 때 4 번 호출되었습니다. 나는 이것이 얼마나 빨리 PC의 기능인지 짐작한다. 따라서 위의 코드는 결함이 있다고 말할 수 있습니다. 다른 아이디어? – user1438082

+0

공정하기 때문에 당신의 대답은 아주 좋고 내가 사용할 수있는 최선이라고 생각합니다. – user1438082