我在写问题标题时已经阅读了建议的帖子,但无济于事。该代码看起来像我的,但我正在做的事情可能是错误的。我也想在此期间添加一些问题。
我正在编写一个将同时运行Timer
和Timer
的程序。
当用户按下开始按钮时,它将触发FileSystemWatcher
和FileSystemWatcher
。
只要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}}