none
Event watcher RRS feed

  • Question

  • Hi Experts, 

    I have an event watcher running on topshelf windows service. The event watcher works as expected ,on start up it tries to process existing files in the folder & then wait for the new one.

    Am facing the following listed issues

    1. Not processing all the files on startup at times.

    2. The existing process method is called on startup how can I call the same method safely again repetitively to process the files which didn't got cached for processing. 


    Please find the code block below for reference and am just new to C# so exact reference guidance is highly supportive. I tried playing with sliding with increasing duration still it didn't helped.

    class FileWatch
        {
            private static MemoryCache FilesToProcess = MemoryCache.Default;
            private FileSystemWatcher inputFileWatcher;
    
            public bool Start()
            {
    
                var directoryToWatch = @"Some directory path";
    
                
                ProcessExistingFiles(directoryToWatch);
    
                inputFileWatcher = new FileSystemWatcher(directoryToWatch);
    
                inputFileWatcher.IncludeSubdirectories = true;
                inputFileWatcher.InternalBufferSize = 32768; // 32 KB
                inputFileWatcher.Filter = "*.*";
                inputFileWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Attributes;
    
                inputFileWatcher.Created += FileCreated;
                inputFileWatcher.Changed += FileChanged;
                inputFileWatcher.Error += WatcherError;
    
                inputFileWatcher.EnableRaisingEvents = true;
                
    
                return true;
    
            }
    
              
    
            public bool Stop()
            {
                inputFileWatcher.Dispose();
    
                return true;
            }
    
    
            private void ProcessExistingFiles(string inputDirectory)
            {
                
                foreach (var filePath in Directory.EnumerateFiles(inputDirectory, "*.*", SearchOption.AllDirectories))
                {
                    AddToCache(filePath);
                }
            }
    
            private void FileCreated(object sender, FileSystemEventArgs e)
            {
              
                if (!IsReadOnly(e.FullPath))
                {
                    AddToCache(e.FullPath);
                }
            }
    
            private void FileChanged(object sender, FileSystemEventArgs e)
            {
              
                if (!IsReadOnly(e.FullPath))
                {
                    AddToCache(e.FullPath);
                }
            }
    
    
    
            private void WatcherError(object sender, ErrorEventArgs e)
            {
                ProcessExistingFiles(@"Some directory path");
            }
    
            private void AddToCache(string fullPath)
            {
                var item = new CacheItem(fullPath, fullPath);
    
                var policy = new CacheItemPolicy
                {
                    RemovedCallback = ProcessFile,
                    SlidingExpiration = TimeSpan.FromSeconds(2),
                };
    
                FilesToProcess.Add(item, policy);
            }
    
            private void ProcessFile(CacheEntryRemovedArguments args)
            {
    
                if (args.RemovedReason == CacheEntryRemovedReason.Expired)
                {
                    Process(args.CacheItem.Key);
                }
                else
                {
                }
            }
    
            private static bool IsReadOnly(string filePath)
            {
                FileInfo fi = new FileInfo(filePath);
                return fi.IsReadOnly;
            }
    
        }
    }
    

    Thanks

    Priya


    • Edited by Priya Bange Thursday, March 12, 2020 5:13 PM .
    Thursday, March 12, 2020 5:08 PM

All replies

  • Hello,

    How are you testing this functionality outside of a production environment? For example, manually creating files via Windows Explorer, changing to and from read only in Explorer. Have you tried using Debugger.Launch to invoke a debug session along with breakpoints?

    Also consider using TraceListener to assist in debugging.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Thursday, March 12, 2020 6:50 PM
    Moderator
  • Hello,

    How are you testing this functionality outside of a production environment? For example, manually creating files via Windows Explorer, changing to and from read only in Explorer. Have you tried using Debugger.Launch to invoke a debug session along with breakpoints?

    Also consider using TraceListener to assist in debugging.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Dear Ma'am,

    There is another automotive process that writes files every 15-20 seconds on the directory under event watcher. I have tried both service and debug mode. 

    The solution does work as expected but at times its skipping some files to be processed. I tried some verbose debugging and found the below code block is skipping it... So if the below code skips any file is it possible to call the Process Existing files method again safely. Please advice

    Thanks 

    Priya

    private void ProcessFile(CacheEntryRemovedArguments args)
            {
    
                if (args.RemovedReason == CacheEntryRemovedReason.Expired)
                {
                    Process(args.CacheItem.Key);
                }


    • Edited by Priya Bange Friday, March 13, 2020 1:06 AM .
    Friday, March 13, 2020 1:05 AM
  • hello friend  try the bellow code

    First all the existing files strored ina a array and then for each file created chech the file name from the array then process

    inputFileWatcher.Changed += new FileSystemEventHandler(FileCreated);
    
    
    void FileCreated(object sender, FileSystemEventArgs e)
    {
    // your code
    
    }


    Friday, March 13, 2020 6:25 AM