2017-07-24 217 views
0

我寫了一個小程序,作爲Windows服務運行,它將收件箱文件夾的文件移動到接收的另一個位置。 但隨機它停止工作(服務仍在運行,進程不崩潰)。如果我將它們移出收件箱並返回,它會再次啓動。 任何提示改善?Filesystemwatcher隨機停止工作

//CIPCoyService.cs 


using System; 
using System.Diagnostics; 
using System.IO; 
using System.ServiceProcess; 
using System.Threading; 

namespace CopyCIP 
{ 
    public partial class CIPCopyService : ServiceBase 
    { 
     public CIPCopyService() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnStart(string[] args) 
     {   
      // start the triggers 
      initXML(); 
      initPDF(); 
      initCSV(); 
     } 

     private static void initXML() 
     { 
      FileSystemWatcher WatcherXML = new FileSystemWatcher(); 
      WatcherXML.Path = @"C:\xxx\baseDir\inbox"; 
      WatcherXML.IncludeSubdirectories = false; 
      WatcherXML.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName; 
      WatcherXML.Filter = "*.xml"; 
      WatcherXML.Created += new FileSystemEventHandler(Watcher_ChangedXML); 
      WatcherXML.EnableRaisingEvents = true; 

     } 

     private static void initPDF() 
     { 
      FileSystemWatcher WatcherPDF = new FileSystemWatcher(); 
      WatcherPDF.Path = @"C:\xxx\baseDir\inbox"; 
      WatcherPDF.IncludeSubdirectories = false; 
      WatcherPDF.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName; 
      WatcherPDF.Filter = "*.pdf"; 
      WatcherPDF.Created += new FileSystemEventHandler(Watcher_ChangedPDF); 
      WatcherPDF.EnableRaisingEvents = true; 

     } 

     private static void initCSV() 
     { 
      FileSystemWatcher WatcherCSV = new FileSystemWatcher(); 
      WatcherCSV.Path = @"C:\xxx\baseDir\inbox"; 
      WatcherCSV.IncludeSubdirectories = false; 
      WatcherCSV.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName; 
      WatcherCSV.Filter = "*.csv"; 
      WatcherCSV.Created += new FileSystemEventHandler(Watcher_ChangedCSV); 
      WatcherCSV.EnableRaisingEvents = true; 

     } 

     private static void Watcher_ChangedXML(object sender, FileSystemEventArgs e) 
     { 
      //move the XML stuff 
      string XMLPath = @"\\xxx\d$\CIP\Admin\Prod\SN\Import\Eingang\eSCHKG\"; 

      if (File.Exists(e.FullPath)) 

       // Ensure that the target does not exist. 
       if (File.Exists(Path.Combine(XMLPath,e.Name))) 
        File.Delete(Path.Combine(XMLPath, e.Name)); 

       WaitReady(e.FullPath); 
       try 
       { 

        File.Move(e.FullPath, Path.Combine(XMLPath, e.Name)); 
       } 
       catch (IOException ex) 
       { 
        eventWriteEx(ex, "XML"); 
       } 
     } 

     private static void Watcher_ChangedPDF(object sender, FileSystemEventArgs e) 
     { 
      // move the PDF stuff 
      string PDFPath = @"\\xxx\d$\CIP\Admin\Prod\SN\Import\Eingang\eSCHKG\PDF\"; 

      if (File.Exists(e.FullPath)) 

       // Ensure that the target does not exist. 
       if (File.Exists(Path.Combine(PDFPath, e.Name))) 
        File.Delete(Path.Combine(PDFPath, e.Name)); 

       WaitReady(e.FullPath); 
       try 
       { 
        File.Move(e.FullPath, Path.Combine(PDFPath, e.Name)); 
       } 
       catch (IOException ex) 
       { 
        eventWriteEx(ex, "PDF"); 
       } 
     } 

     private static void Watcher_ChangedCSV(object sender, FileSystemEventArgs e) 
     { 
      // move the CSV stuff 
      string CSVPath = @"\\xxx\d$\CIP\Admin\Prod\SN\Import\Eingang\eSCHKG\CSV\"; 

      if (File.Exists(e.FullPath)) 

       // Ensure that the target does not exist. 
       if (File.Exists(Path.Combine(CSVPath, e.Name))) 
        File.Delete(Path.Combine(CSVPath, e.Name)); 

       WaitReady(e.FullPath); 
       try 
       { 
        WaitReady(e.FullPath); 
        File.Move(e.FullPath, Path.Combine(CSVPath, e.Name)); 
       } 
       catch (Exception ex) 
       { 
        eventWriteEx(ex, "CSV"); 
       } 
     } 

     private static void eventWriteEx(Exception ex, string what) 
     { 
      string eSource = "CIPCopyService"; 

      if (!EventLog.SourceExists(eSource)) 
       EventLog.CreateEventSource(eSource, "CIPEvents"); 

      EventLog.WriteEntry("CIPCopy Exception" + what, ex.Message + "Trace" + ex.StackTrace, EventLogEntryType.Error); 
     } 

     private static void eventWriteInfo(string what) 
     { 
      string eSource = "CIPCopyService"; 

      if (!EventLog.SourceExists(eSource)) 
       EventLog.CreateEventSource(eSource, "CIPEvents"); 

      EventLog.WriteEntry(eSource, what); 
     } 


     public static void WaitReady(string fileName) 
     { 
      while (true) 
      { 
       try 
       { 
        using (Stream stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) 
        { 
         if (stream != null) 
         { 
          eventWriteInfo(string.Format("Output file {0} ready.", fileName)); 
          break; 
         } 
        } 
       } 
       catch (FileNotFoundException ex) 
       { 
        eventWriteEx(ex, string.Format("Output file {0} not yet ready ({1})")); 
       } 
       catch (IOException ex) 
       { 
        eventWriteEx(ex, string.Format("Output file {0} not yet ready ({1})")); 
       } 
       catch (UnauthorizedAccessException ex) 
       { 
        eventWriteEx(ex, string.Format("Output file {0} not yet ready ({1})")); 
       } 
       Thread.Sleep(500); 
      } 
     } 

     protected override void OnStop() 
     { 

     } 
    } 
} 
+0

我不會完全依靠FSW,它最好有一個額外的獨立掃描更改 - 即由計時器觸發。 –

+0

爲什麼你需要這個事件(或者FileSystemWatcher)呢?只需使用計時器並將處理後的文件移動到目標文件夾即可。然後,收件箱始終只包含未處理的文件。您可以通過File.GetCreationTime命令來先處理最舊的文件。 –

回答

2

FileSystemWatcher如果在很短的時間內觸摸很多文件,則會受到限制。 FileSystemWatcher的內部緩衝區已滿,在緩衝區有空閒空間之前發生的任何更改都無法處理。您可以將緩衝區增加到最大值65536:

watcherXML.InternalBufferSize = 65536; 

但即便如此也有一個限制。如果您期望的文件量非常大,則應該使用Timer並將所有現有文件移至新位置;

private static void initXML() 
{ 
    Timer timer = new Timer(); 
    timer.Interval = 1000; 
    timer.Tick += (y,z) => 
    { 
     foreach(string file in Directory.GetFiles(@"C:\xxx\baseDir\inbox") 
     { 
      MoveFile(file); 
     } 
    }; 

    timer.Start(); 
} 

private void MoveFile(string file) 
{ 
    string XMLPath = @"\\xxx\d$\CIP\Admin\Prod\SN\Import\Eingang\eSCHKG\"; 
    string fileName = Path.GetFileName(file); 
    if (File.Exists(file)) 
     // Ensure that the target does not exist. 
     if (File.Exists(Path.Combine(XMLPath,fileName))) 
      File.Delete(Path.Combine(XMLPath, fileName)); 

     WaitReady(file); 
     try 
     { 
      File.Move(file, Path.Combine(XMLPath, fileName)); 
     } 
     catch (IOException ex) 
     { 
      eventWriteEx(ex, "XML"); 
     } 
    }