我写了一个小程序,我作为Windows服务运行,它将收件箱文件夹的文件移动到另一个位置。 但随机它停止工作(服务仍在运行,进程没有崩溃)。如果我只是将它们移出收件箱并返回,它会再次启动。 有任何改善的提示吗?
//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 :(得分: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");
}
}