2017-07-24 2 views
0

Ich habe ein kleines Programm geschrieben, das ich als Windows-Dienst ausführe, der Dateien eines Posteingangs-Ordners an einen anderen Ort beim Empfang verschiebt. Aber nach dem Zufallsprinzip funktioniert es nicht mehr (Dienst läuft noch, Prozess stürzt nicht ab). Wenn ich sie einfach aus dem Posteingang und zurück schiebe, fängt es wieder an. Irgendwelche Hinweise zur Verbesserung?Filesystemwatcher stopped zufällig funktioniert

//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

ich nicht ganz auf einer FSW verlassen würde, seine besten eine zusätzliche unabhängige Schwung für Änderungen haben - das heißt durch einen Timer ausgelöst. –

+0

Warum benötigen Sie dieses Ereignis (oder den FileSystemWatcher) überhaupt? Verwenden Sie einfach einen Timer und verschieben Sie die verarbeiteten Dateien in den Zielordner. Der Posteingang enthält dann immer nur die unverarbeiteten Dateien. Sie können nach 'File.GetCreationTime' bestellen, um die ältesten Dateien zuerst zu verarbeiten. –

Antwort

2

FileSystemWatcher hat eine Einschränkung, wenn viele Dateien in kürzester Zeit berührt werden. Der interne Puffer der FileSystemWatcher ist voll und alle Änderungen, die auftreten, bis der Puffer freien Speicherplatz hat, können nicht behandelt werden. Sie können den Puffer auf maximal 65536 erhöhen:

watcherXML.InternalBufferSize = 65536; 

Aber auch das hat eine Einschränkung. Wenn Sie wirklich große Mengen an Dateien erwarten, sollten Sie wahrscheinlich eine Timer verwenden und alle vorhandenen Dateien an den neuen Speicherort verschieben;

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"); 
     } 
    } 
Verwandte Themen