Filesystemwatcher随机停止工作

时间:2017-07-24 12:41:19

标签: c# filesystemwatcher

我写了一个小程序,我作为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()
        {

        }
    }
}

1 个答案:

答案 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");
        }
    }