Hello Everyone.
I'm using a FileProcessor class with FileSystemWatcher (there are many examples around the web) to process files queued by the FileSystemWatcher.
I modified this one to suit my needs, but i'm missing something - when it finishes processing the job and returns to the UI thread, my FileSystemWatcher stops watching for files.
I'm using the other program i made as example and there i didn't had to restart the FileSystemWatcher ; it was running all the time watching for files that were created.
This is how i'm debugging trying to find the issue:
1 - Program Starts
2 - Timer and FileSystemWatcher are running
2.1 - If no file is created, timer restarts. If a file is created, timer restarts.
2.2 - If timer ends and there are files in the queue, process jobs related to those files.
3 - After processing, ends the FileProcessor thread and returns to the UI
4 - Timer gets restarted (i do restart it on the UI thread after processing the files), but FileSystemWatcher stops working.
Should i restart the FileSystemWatcher also ? I'm in doubt because if i do so i might lose some file event while the process is running (it'll be a long process).
Any help is appreciated. Thanks !
I'll post my code here.
FileProcessor.cs
Form1 - Starts the timer and the enable the EnableRaisingEvents property
Timer tick - where i restart the timer if needed or process things on the queue
I know i've been posting some newbie questions since yesterday - aside reading a few articles on MSDN i'm trying to do my best to learn from posts/other users.
Again, thanks in advance !
I'm using a FileProcessor class with FileSystemWatcher (there are many examples around the web) to process files queued by the FileSystemWatcher.
I modified this one to suit my needs, but i'm missing something - when it finishes processing the job and returns to the UI thread, my FileSystemWatcher stops watching for files.
I'm using the other program i made as example and there i didn't had to restart the FileSystemWatcher ; it was running all the time watching for files that were created.
This is how i'm debugging trying to find the issue:
1 - Program Starts
2 - Timer and FileSystemWatcher are running
2.1 - If no file is created, timer restarts. If a file is created, timer restarts.
2.2 - If timer ends and there are files in the queue, process jobs related to those files.
3 - After processing, ends the FileProcessor thread and returns to the UI
4 - Timer gets restarted (i do restart it on the UI thread after processing the files), but FileSystemWatcher stops working.
Should i restart the FileSystemWatcher also ? I'm in doubt because if i do so i might lose some file event while the process is running (it'll be a long process).
Any help is appreciated. Thanks !
I'll post my code here.
FileProcessor.cs
C#:
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)
{
if (counter <= 0) //Timer is over, proceed with execution
{
lock(locker)
{
while (FilesQueue.Count > 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 });
}//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
}
}
Form1 - Starts the timer and the enable the EnableRaisingEvents property
C#:
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(); //Restarts the timer
break;
}
}
Timer tick - where i restart the timer if needed or process things on the queue
C#:
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();
}
I know i've been posting some newbie questions since yesterday - aside reading a few articles on MSDN i'm trying to do my best to learn from posts/other users.
Again, thanks in advance !