//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); } }