FileSystemWatcher和计时器一起

时间:2018-09-05 22:03:03

标签: c# multithreading timer filesystemwatcher

我在写问题标题时已经阅读了建议的帖子,但无济于事。该代码看起来像我的,但我正在做的事情可能是错误的。我也想在此期间添加一些问题。

我正在编写一个将同时运行TimerTimer的程序。 当用户按下开始按钮时,它将触发FileSystemWatcherFileSystemWatcher

只要Timer正在监视文件夹,OnCreated就会运行。 如果没有收到文件,则什么也不会发生。 如果已创建文件,请将其放入Timer事件内部,然后重新启动FileProcessor

在创建文件并且计时器到期之后,它开始在FileProcessor类上进行工作。

我看到许多Timer类的样本都适合特定的需求,这就是我对我所做的。更改为符合我的要求。

因此,我等到FileProcessor到期后才开始处理,而不是在入队时立即开始工作。

直到现在一切都很好,但是这是发生了什么: 当FileSystemWatcher类完成其工作时,FileProcessor停止监视文件夹。 FileSystemWatcher线程结束后未检测到文件,计时器正常重启。我想寻求帮助,看看我是否应该使用其他组件而不是 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Text; using System.Windows.Forms; using Telerik.WinControls; namespace DI_Plot_2018 { public partial class RadForm1 : Telerik.WinControls.UI.RadForm { FileSystemWatcher InputFileWatcher; FileProcessor TIFFProcessor; static Timer timer1; bool RestartTimer; LoadInternalSettings InternalSettings; double CurrentCounter; public RadForm1() { InitializeComponent(); RestartTimer = false; InternalSettings = new LoadInternalSettings(); //counter = Int32.Parse(InternalSettings.Timer); timer1 = new Timer(); timer1.Tick += new EventHandler(SecondElapsed); timer1.Enabled = false; TIFFProcessor = new FileProcessor(); LoadControls(InternalSettings); } DateTime start; double s; private void CountDown() { start = DateTime.Now; s = Double.Parse(InternalSettings.Timer); timer1.Start(); } private void SecondElapsed(object sender, EventArgs e) { double remainingSeconds = s - (DateTime.Now - start).TotalSeconds; if(RestartTimer == true) { timer1.Stop(); CountDown(); RestartTimer = false; } else if (remainingSeconds <= 0) { timer1.Stop(); if(TIFFProcessor.FilesQueue.Count > 0) { TIFFProcessor.FireProcessing(CurrentCounter); } CountDown(); } var x = TimeSpan.FromSeconds(remainingSeconds); CurrentCounter = x.Seconds; TimerTextBox.Text = x.Seconds.ToString(); } private void FileCreated(Object sender, FileSystemEventArgs e) { if (e.ChangeType == WatcherChangeTypes.Created) { TIFFProcessor.EnqueueJob(e.FullPath, CurrentCounter); RestartTimer = true; } } private void ButtonChangedEventHandler(object sender, EventArgs e) { Telerik.WinControls.UI.RadButton bt = sender as Telerik.WinControls.UI.RadButton; string buttonName = (String)bt.Name; SwitchButtonImage buttonImageSwitch; switch (buttonName) { case "StartButton": { InputFileWatcher = new FileSystemWatcher(InputFolderTextBox.Text); InputFileWatcher.Created += new FileSystemEventHandler(FileCreated); InputFileWatcher.Filter = "*.tif"; InputFileWatcher.EnableRaisingEvents = true; StopButton.Enabled = true; StartButton.Enabled = false; CountDown(); //TimerStart(); break; } case "StopButton": { InputFileWatcher.EnableRaisingEvents = false; timer1.Stop(); StopButton.Enabled = false; StartButton.Enabled = true; break; } case "ImageRotationButton": { buttonImageSwitch = new SwitchButtonImage(ImageRotationButton, "ImageRotationIndex"); break; } case "ImageOrientationButton": { buttonImageSwitch = new SwitchButtonImage(ImageOrientationButton, "ImageOrientationIndex"); break; } case "InputFolderBrowseButton": { InputFolderTextBox.Text = new ItemSaveToConfig.SelectFolderSaveProperty(InputFolderTextBox.Text, "Select the input folder", "InputFolder").folderSelect; break; } case "OutputFolderBrowseButton": { OutputFolderTextBox.Text = new ItemSaveToConfig.SelectFolderSaveProperty(OutputFolderTextBox.Text, "Select the output folder", "OutputFolder").folderSelect; break; } } } private void LoadControls(LoadInternalSettings Settings) { InputFolderTextBox.Text = InternalSettings.InputFolder; OutputFolderTextBox.Text = InternalSettings.OutputFolder; NumberOfZonesTextBox.Text = InternalSettings.NumberOfZones; FirstZoneWidthTextBox.Text = InternalSettings.FirstZoneWidth; LastZoneWidthTextBox.Text = InternalSettings.LastZoneWidth; ZoneAreaWidthTextBox.Text = InternalSettings.ZoneAreaWidth; ZoneAreaHeightTextBox.Text = InternalSettings.ZoneAreaHeight; ZoneWidthTextBox.Text = InternalSettings.ZoneWidth; TimerTextBox.Text = InternalSettings.Timer; ZoneWidthTextBox.Text = InternalSettings.ZoneWidth; ImageRotationButton.ChangeClickCountFromConfigFile(Int32.Parse(InternalSettings.ImageRotationIndex)); ImageOrientationButton.ChangeClickCountFromConfigFile(Int32.Parse(InternalSettings.ImageOrientationIndex)); //xmlRotateFront.ChangeClickCountFromConfigFile(internalSettings.XMLtoPPFRotateFrontIndex); var RotatePreview = new SwitchButtonImage(ImageRotationButton, "ImageRotationIndex"); var OrientationPreview = new SwitchButtonImage(ImageOrientationButton, "ImageOrientationIndex"); } private void TextBoxChangedEventHandler(object sender, EventArgs e) { Telerik.WinControls.UI.RadTextBox TxtBx = sender as Telerik.WinControls.UI.RadTextBox; string TxtName = TxtBx.Name; switch (TxtName) { case "NumberOfZonesTextBox": { NumberOfZonesTextBox.Text = new ItemSaveToConfig.ChangeAndSaveTextBox(NumberOfZonesTextBox.Text, "NumberOfZones", false).TextToApply; break; } case "ZoneWidthTextBox": { ZoneWidthTextBox.Text = new ItemSaveToConfig.ChangeAndSaveTextBox(ZoneWidthTextBox.Text, "ZoneWidth", false).TextToApply; break; } case "FirstZoneWidthTextBox": { ZoneWidthTextBox.Text = new ItemSaveToConfig.ChangeAndSaveTextBox(FirstZoneWidthTextBox.Text, "FirstZoneWidth", false).TextToApply; break; } case "LastZoneWidthTextBox": { ZoneWidthTextBox.Text = new ItemSaveToConfig.ChangeAndSaveTextBox(LastZoneWidthTextBox.Text, "LastZoneWidth", false).TextToApply; break; } } } private void RadForm1_FormClosed(object sender, FormClosedEventArgs e) { timer1.Stop(); new ItemSaveToConfig.SelectItemSaveProperty("Timer", TimerTextBox.Text.ToString()); //WaitingTimer.Stop(); Environment.Exit(0); } } }

与此有关的一个问题是:我想检测程序运行时创建的文件,并在以后处理它们。为此,我添加了一个单独的计数器,以在循环开始出队之前捕获队列的原始计数。这是个好方法吗?

谢谢!

表单代码:

    using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Timers;
using DI_Plot_2018.IZData;

namespace DI_Plot_2018
{
    class FileProcessor : IDisposable
    {
        // Create an AutoResetEvent EventWaitHandle
        private EventWaitHandle eventWaitHandle = new AutoResetEvent(false);
        private readonly object locker = new object();
        private Thread worker;                
        public Queue<string> FilesQueue = new Queue<string>();
        private Queue<KeyValuePair<string, List<string>>> JobsQueue = new Queue<KeyValuePair<string, List<string>>>();
        private Dictionary<string, List<string>> FullJob = new Dictionary<string, List<string>>();
        #region IDisposable Members
        public FileProcessor()
        {
            worker = new Thread(new ThreadStart(Work));
            worker.IsBackground = true;
        }
        public void FireProcessing(double counter)
        {
            int filesQueuedCounter = FilesQueue.Count;
            if (counter <= 0) //Timer is over, proceed with execution
            {
                lock(locker)
                {                    
                    while (filesQueuedCounter > 0)
                    {
                        string currFilename = FilesQueue.Dequeue(); //Dequeue filename
                        JobDetails CurrentJobInfo = new JobDetails(currFilename); //Get information about the job 
                        //Checking if dict already has the key - if it does, add the filename at the key position
                        if (FullJob.ContainsKey(CurrentJobInfo.JobNameWithoutColor))
                            FullJob[CurrentJobInfo.JobNameWithoutColor].Add(currFilename);
                        else //if it doesn't, add the new key and start the value (List<string>) with the current filename
                            FullJob.Add(CurrentJobInfo.JobNameWithoutColor, new List<string>() { currFilename });
                        filesQueuedCounter--;
                    }//End while loop - Dequeue all files
                    foreach (var item in FullJob) //Enqueue files in a jobs queue (KeyValuePair queue)
                    {
                        JobsQueue.Enqueue(item);
                    }
                    eventWaitHandle.Set();                    
                    worker.Start();
                }                                    

            }
        }
        public void EnqueueJob(string FileName, double counter)
        {            
            if(counter > 0)
            {
                lock(locker)
                {
                    FilesQueue.Enqueue(FileName);
                }                
            }             
        }
        private void Work()
        {
            while(true)
            {
                KeyValuePair<string, List<string>> JobToRun = new KeyValuePair<string, List<string>>();
                lock (locker)
                {
                    if(JobsQueue.Count > 0)
                    {
                        JobToRun = JobsQueue.Dequeue();
                        if (JobToRun.Key == null) return;
                    }
                    if(JobToRun.Key != null)
                    {
                        ProcessJob(JobToRun);
                    }
                    else
                    {
                        eventWaitHandle.WaitOne();
                    }
                }
            }
        }
        private void ProcessJob(KeyValuePair<string,List<string>> currJob)
        {
            string x = string.Empty;

        }
        public void Dispose()
        {
            // Signal the FileProcessor to exit
            FilesQueue.Enqueue(null);
            JobsQueue.Enqueue(new KeyValuePair<string, List<string>>("aa", new List<string>() { "aa"}));
            // Wait for the FileProcessor's thread to finish
            worker.Join();
            // Release any OS resources
            eventWaitHandle.Close();
        }
        #endregion
    }
}

FileProcessor代码:

{{1}}

0 个答案:

没有答案