Event-driven .NET: use FileSystemWatcher instead of polling for new files

You can use FileSystemWatcher to get notified of file system changes, such as when a file is created.

Here’s an example of reacting to when a JSON file is created:

FileSystemWatcher fileSysWatcher = new FileSystemWatcher(@"C:\Data\", "*.json");
fileSysWatcher.EnableRaisingEvents = true;
fileSysWatcher.Created += (sender, e) =>
{
	Console.WriteLine($"File created {e.FullPath}");
};

Compared to polling, this event-driven approach with FileSystemWatcher is more efficient and simpler.

In the remainder of this article I’ll show an example of how to use FileSystemWatcher to process files enqueued in a filesystem-based message queue.

Example – Processing new message JSON files

I want to implement a filesystem-based message queue.

To enqueue a message, a JSON message file is dropped into C:\Data\MessageQueue\in\.

The message queue processor gets notified when a new file is created, processes it, then dequeues it by moving it to C:\Data\MessageQueue\processed\.

So I only want to get notified when JSON files are added to C:\Data\MessageQueue\in\.

MessageQueueProcessor class

I need to create a FileSystemWatcher that watches the C:\Data\MessageQueue\in\ folder. I can make it only notify me about JSON files by specifying the filter “*.json”. After initializing the FileSystemWatcher, I need to subscribe to the Created event.

public class MessageQueueProcessor : IDisposable
{
	public const string InPath = @"C:\Data\MessageQueue\in";
	public const string ProcessedPath = @"C:\Data\MessageQueue\processed";
	private FileSystemWatcher fileSystemWatcher;


	public void Start()
	{
		fileSystemWatcher = new FileSystemWatcher(InPath, "*.json");
		fileSystemWatcher.EnableRaisingEvents = true;
		fileSystemWatcher.Created += (sender, e) =>
		{
			Console.WriteLine($"Processing enqueued file {e.FullPath}");

			var destFile = Path.Combine(@"C:\Data\MessageQueue\processed", e.Name);

			if (File.Exists(e.FullPath))
			{
				File.Move(e.FullPath, destFile);
			}
		};
	}

	public void Dispose()
	{
		if (fileSystemWatcher != null)
		{
			fileSystemWatcher.Dispose();
		}
	}

}

Using MessageQueueProcessor

I have a console app that uses the MessageQueueProcessor.

static void Main(string[] args)
{
	MessageQueueProcessor messageQueueProcessor = new MessageQueueProcessor();
	messageQueueProcessor.Start();

	Console.WriteLine("Started message queue processor.");

	Console.ReadKey();
}

Results

As soon as I drop message1234.json into the message queue folder, it gets processed, and then moved into the /processed/ folder.

Leave a Comment