Search code examples
asp.net-corefilesystemwatcherasp.net-core-2.1

FileSystemWatcher in an AspNetCore 2.1 BackgroundService\IHostedService


I am trying to use an implementation of the BackgroundService in an AspNet Core 2.1 application. I create a FileSystemWatcher in ExecuteAsync and link the associated events,however, the fsw events are either never fired (unreachable? already disposed?) or its some thing I am doing wrong with this being async or the scope is messed up. I can't seem to figure it out. Following is the relevant code.

public class FSWImpl : BackgroundService
{
    private readonly IHostingEnvironment _env;
    private readonly ILogger<LiftAndShift> _logger;
    private FileSystemWatcher _fsw;

    public LiftAndShift(IHostingEnvironment env, ILogger<FSWImpl> logger)
    {
        _env = env;
        _logger = logger;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Creating new FSW");
        var path = Path.Combine(_env.ContentRootPath, "WebData");
        _fsw = new FileSystemWatcher(path,"*.json");
        _fsw.Created += _fsw_Created;
        _fsw.Changed += _fsw_Changed;
        _fsw.Renamed += _fsw_Renamed;
        _fsw.Error += _fsw_Error;
        return Task.CompletedTask;
    }

    private void _fsw_Error(object sender, ErrorEventArgs e) => _logger.LogInformation("File error");
    private void _fsw_Renamed(object sender, RenamedEventArgs e) => _logger.LogInformation("File Renamed");
    private void _fsw_Changed(object sender, FileSystemEventArgs e) => _logger.LogInformation("File changed");
    private void _fsw_Created(object sender, FileSystemEventArgs e) => _logger.LogInformation("File created");
}  

I register this service in startup as services.AddHostedService<FSWImpl>();


Solution

  • For enabling FileSystemWatcher, you need to set EnableRaisingEvents as True.

    Demo Code:

            protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("Creating new FSW");
            var path = Path.Combine(_env.ContentRootPath, "WebData");
            _fsw = new FileSystemWatcher(path, "*.json");
            _fsw.Created += _fsw_Created;
            _fsw.Changed += _fsw_Changed;
            _fsw.Renamed += _fsw_Renamed;
            _fsw.Error += _fsw_Error;
            _fsw.EnableRaisingEvents = true;
            return Task.CompletedTask;
        }
    

    FileSystemWatcher.cs

        //
        // Summary:
        //     Gets or sets a value indicating whether the component is enabled.
        //
        // Returns:
        //     true if the component is enabled; otherwise, false. The default is false. If
        //     you are using the component on a designer in Visual Studio 2005, the default
        //     is true.
        //
        // Exceptions:
        //   T:System.ObjectDisposedException:
        //     The System.IO.FileSystemWatcher object has been disposed.
        //
        //   T:System.PlatformNotSupportedException:
        //     The current operating system is not Microsoft Windows NT or later.
        //
        //   T:System.IO.FileNotFoundException:
        //     The directory specified in System.IO.FileSystemWatcher.Path could not be found.
        //
        //   T:System.ArgumentException:
        //     System.IO.FileSystemWatcher.Path has not been set or is invalid.
        public bool EnableRaisingEvents { get; set; }