使用FileSystemWatcher和Timer的Windows服务 - 确保一切都被处理掉

Jay*_*Jay 2 .net c# windows-services timer

我创建了一个C#Windows服务应用程序,它启动一个FileSystemWatcher监视目录以创建文件.找到文件后,我实例化一个解析文件(CSV)的自定义类,并使用它的内容调用Web服务.该服务有些异步,并返回一个唯一的编号,必须用于后续调用以检查其进度.在我的进程类中,我创建了一个计时器来不断检查作业是否完成.我在dispose荷兰国际集团和close荷兰国际集团我的计时器时,我与它这样做,但我只是想确保我的类将被垃圾收集,我不会有任何内存泄漏.

代码看起来像这样(为简洁起见):

我的主要服务类:

    protected override void OnStart(string[] args)
    {
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.Path = "path";
        watcher.Filter = "file";
        watcher.Created += new FileSystemEventHandler(watcher_Created);
        watcher.EnableRaisingEvents = true;
    }

    static void watcher_Created(object sender, FileSystemEventArgs e)
    {
        FileProcessor p = new FileProcessor();
        p.Process(e.FullPath);

        //Will this instance of p stick around until the timer within it is finished?
    }
Run Code Online (Sandbox Code Playgroud)

FileProcessor.cs

    class FileProcessor
    {
        private System.Timers.Timer timer = new System.Timers.Timer();
        private string id;

        public FileProcessor()
        {
            timer.Elapsed += new ElapsedEventHandler(OnTimer);
            timer.Enabled = false;
            timer.AutoReset = true;
        }

        public void Process(string filename)
        {
            //Read file <snipped>

            //Call web service and get id
            id = CallWebService();

            //Create a timer for 10 seconds and start it
            timer.Interval = 10000;
            timer.Enabled = true;
        }


        private bool IsFinished(string id)
        {
            //Call web service to see if job is finished, true if finished
            //<snipped>
        }


        private void ProcessResults()
        {
            //Job is finished, process results

            //Call cleanup method to dispose of timer
            Cleanup();
        }

        private void OnTimer(object source, ElapsedEventArgs e)
        {
            if (!IsFinished(id))
            {
                //Keep timer running, check result again next timer event
                return;
            }
            else
            {
                //Stop timer
                timer.Stop();

                //Process Results
                ProcessResults(response);
            }
        }


        private void Cleanup()
        {
            timer.Close();
            timer.Dispose();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,在我的计时器被销毁之前,我的"p"实例是否应该坚持(不是GC)?会被毁掉吗?我的FileProcessor类是否需要实现IDisposable,以便将其包装在using块中?我并不担心这是单线程,因为我只希望它每天处理一个文件,并且该过程完成并返回观察下一个要创建的文件的时间不应超过10分钟.

Dav*_*age 5

你走在正确的轨道上. FileSystemWatcher实现Component类,它要求您在使用后处置它.由于这种情况,正确的方法是让您的FileProcessor类按照您的建议实现IDisposable.

由于您将长时间使用FileProcessor对象,因此您将无法使用using语句.这是因为对象在完成其工作之前会尝试处理.

在这种情况下,我会在FileProcessor上实现一个事件,以便在处理完成时通知消费者.完成后,我将在FileProcessor对象上调用Dispose方法.的处置方法应执行该对象所需要的所有清理- IE:计时器,观察者等

供您参考,这是一篇很好的文章,它为何时以及如何使用IDisposable接口提供了一些指导.此外,作为一种好的做法,您将希望将消费者中的调用包装在try/catch块中 - 您需要确保无论发生什么情况,您都会尝试释放资源.