2017-07-24 130 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"); 
     } 
    }