Domore.Async.FileSystemWatching 10.4.0

dotnet add package Domore.Async.FileSystemWatching --version 10.4.0
                    
NuGet\Install-Package Domore.Async.FileSystemWatching -Version 10.4.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Domore.Async.FileSystemWatching" Version="10.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Domore.Async.FileSystemWatching" Version="10.4.0" />
                    
Directory.Packages.props
<PackageReference Include="Domore.Async.FileSystemWatching" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Domore.Async.FileSystemWatching --version 10.4.0
                    
#r "nuget: Domore.Async.FileSystemWatching, 10.4.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Domore.Async.FileSystemWatching@10.4.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Domore.Async.FileSystemWatching&version=10.4.0
                    
Install as a Cake Addin
#tool nuget:?package=Domore.Async.FileSystemWatching&version=10.4.0
                    
Install as a Cake Tool

Domore.Async.FileSystemWatching

React to file-system changes with async callbacks. Domore.Async.FileSystemWatching creates, configures, shares, restarts, and disposes FileSystemWatcher instances for you. You write the handler.

Install the package with dotnet add package Domore.Async.FileSystemWatching.

Watch a directory

using Domore.IO;

using var subscription = FileSystemEventTasks.Add(
    @"C:\logs",
    new FileSystemEventOptions { FileFilter = "*.log", IncludeSubdirectories = true },
    async (e, token) => {
        Console.WriteLine($"{e.ChangeType}: {e.Name}");
        await ProcessAsync(e.FullPath, token);
    });

The callback receives the FileSystemEventArgs for each Created, Changed, Deleted, or Renamed event (for renames it's a RenamedEventArgs) and a cancellation token. Dispose the returned subscription to remove the callback. Omit the options to watch every file in the directory, not including subdirectories.

Watching starts in the background shortly after Add returns, so changes made immediately afterward may not be reported. If you need to know exactly when watching begins, use FileSystemEventProvider and its ready callback.

Options

Option Default Description
FileFilter all files A wildcard filter such as *.log.
IncludeSubdirectories false Also watch subdirectories.
NotifyFilter all NotifyFilters Which kinds of changes raise events.
InternalBufferSize 65,536 The size in bytes of the watcher's internal buffer. Larger buffers are less likely to overflow when many changes happen at once.

FileSystemEventOptions is a record, so options with the same values are equal.

How events are delivered

  • Watchers are shared. Subscriptions to the same directory with equal options share a single FileSystemWatcher. Paths are compared by their full path, and on Windows the directory's case sensitivity is detected. When the last subscription is removed, the watcher is stopped after a short delay, so a quick unsubscribe and resubscribe reuses it.
  • Events arrive in order. Each event is delivered to every subscription of a watcher at the same time, and the next event isn't delivered until every callback has finished.
  • Callbacks run where you subscribed. If Add is called with a SynchronizationContext (for example, on a UI thread), callbacks run on that context. Otherwise, they run on the thread pool.
  • Failures are isolated. An exception thrown by one callback doesn't affect other subscriptions or stop the watcher.

Handle results and errors

FileSystemEventTasks reports outcomes through optional static handlers. Each receives a FileSystemEventResult with the Subscription, whether it was Canceled, and any Exception:

FileSystemEventTasks.OnSubscriptionEventError = (result, token) => {
    Console.Error.WriteLine($"A file handler failed: {result.Exception.Message}");
    return Task.CompletedTask;
};

FileSystemEventTasks.OnManagerError = (result, token) => {
    Console.Error.WriteLine($"Could not watch the directory: {result.Exception.Message}");
    return Task.CompletedTask;
};

FileSystemEventTasks.OnUnhandledError = (exception, token) => {
    Console.Error.WriteLine($"The watcher failed: {exception.Message}");
    return Task.FromResult(true); // restart the watcher
};
Handler Called when
OnSubscriptionEventComplete A callback finishes handling an event.
OnSubscriptionEventError A callback throws.
OnSubscriptionEventCanceled A callback is canceled because its watcher stopped.
OnManagerError Adding or removing a subscription fails, for example because the directory doesn't exist.
OnManagerCanceled Adding or removing a subscription is canceled.
OnUnhandledError The watcher itself fails, for example when its buffer overflows. Return true to restart the watcher after a short delay, or false to stop it.

Stream events

FileSystemEventProvider exposes a single watcher as an IAsyncEnumerable<FileSystemEventArgs>, for code that would rather await foreach than subscribe:

using Domore.IO;

var provider = new FileSystemEventProvider(@"C:\data", new FileSystemEventOptions { FileFilter = "*.csv" });

await foreach (var e in provider.Events(
    ready: token => {
        Console.WriteLine("Watching.");
        return Task.CompletedTask;
    },
    token: cancellationToken)) {
    Console.WriteLine($"{e.ChangeType}: {e.Name}");
}

The optional ready callback runs once the watcher is running, so changes made from it or after it are reported. The watcher is disposed when the enumeration ends. That happens when the loop exits or the watcher fails. Canceling the token also ends it, by throwing an OperationCanceledException. Invalid paths or options throw a FileSystemWatcherInitializationException.

Custom subscriptions

For more control, derive from FileSystemEventSubscription and manage subscriptions with your own FileSystemEventManager. Its handlers are the same as those on FileSystemEventTasks, but they're per instance:

using Domore.IO;

public sealed class ReportImporter : FileSystemEventSubscription {
    protected override async Task Receive(FileSystemEventArgs e, CancellationToken token) {
        await ImportAsync(e.FullPath, token);
    }
}

var manager = new FileSystemEventManager {
    OnSubscriptionEventError = (result, token) => LogAsync(result.Exception)
};

var importer = new ReportImporter();
await manager.Add(importer, @"C:\reports", options: null, token);
// ...
await manager.Remove(importer, @"C:\reports", options: null, token);

Supported frameworks

.NET Framework 4.6.2, .NET 6, .NET 8, and .NET 10.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.4.0 0 9/24/2026
10.3.1 79 9/18/2026
10.2.1 141 1/10/2026
10.2.0 132 1/10/2026