//ProcessFiles method called every 1 sec
 //Duplicate events are generated but are not getting executed in this case
 //However it may happen that the events gets duplicated before this function is even called (that in less than 1000ms)
 //Hence we can use MemoryCache as a workaround
 public static void ProcessFiles(object stateInfo)
 {
     foreach (var fileName in FilesToProcess.Keys)
     {
         // as we don't need the out param, hence out _
         if (FilesToProcess.TryRemove(fileName, out _))
         {
             var fileProcessor = new FileProcessor(fileName);
             fileProcessor.Process();
         }
     }
 }
        //Called when a cache item expires and item not accessed till two seconds
        //Note: This method also can raise exceptions if there are too many operations and multiple two operations are changing
        //one file from diffrent threads
        private static void ProcessFile(CacheEntryRemovedArguments args)
        {
            WriteLine($"Cache item removed: {args.CacheItem.Key} becayse {args.RemovedReason}");

            if (args.RemovedReason == CacheEntryRemovedReason.Expired)
            {
                var fileProcessor = new FileProcessor(args.CacheItem.Key);
                fileProcessor.Process();
            }
            else
            {
                WriteLine($"Warning: {args.CacheItem.Key} was removed unexpectedly and may not");
            }
        }
        //Creating event handler methods
        public static void FileCreated(object sender, FileSystemEventArgs e)
        {
            WriteLine($"File created: {e.Name} - type: {e.ChangeType}");

            if (_applicationRunningMethod == (int)ApplicationRunningMethod.Normally)
            {
                var fileProcessor = new FileProcessor(e.FullPath);
                fileProcessor.Process();
            }
            else if (_applicationRunningMethod == (int)ApplicationRunningMethod.UsingConcurrentDictionary)
            {
                //Hence instead of calling the Process method directly like above, we're using TryAdd method of concurrent dictionary
                //and it will only add the event if there's not one already present
                FilesToProcess.TryAdd(e.FullPath, e.FullPath);
            }
            else
            {
                AddToCache(e.FullPath);
            }
        }