FileProcessor thread not ending

pablobhz

Member
Joined
Sep 4, 2018
Messages
6
Programming Experience
1-3
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
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 !
 
Back
Top Bottom