Watch/touch in .NET Core

Publish date: May 2, 2019
Tags: .net core, c#

An inspiration

Recently I went through an amazing book on Node.js called: Node.js 8 the Right Way , by Jim Wilson. There was a nice example showing how to watch for file changes in node. This was just a few lines of code, plus a bash command which would touch (create/modify) a file every few seconds. This was a setup to demonstrate the way in which node can exchange messages and watch for file changes. Afterwards he recreated the app multiple times, adding more robustness and functionalities. Ending up with the grand ZeroMQ finale! It was really a joy to follow this!

.NET Core version

Lately I thought to myself: “This should be possible in .NET Core, why wouldn’t it?” So here is my first try:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Watch
{
   class Program
   {
       static void Main(string[] args)
       {
           Parallel.Invoke(
               () => WatchForChanges(),
               () => WriteStuff()
           );
       }

       public static void WatchForChanges()
       {
           using (var watcher = new FileSystemWatcher(Environment.CurrentDirectory))
           {
               watcher.NotifyFilter = NotifyFilters.LastAccess | 
                                      NotifyFilters.LastWrite;
               watcher.Changed += (source, e) => System.Console.WriteLine($"Changed {e.Name} at {DateTime.Now}");
               watcher.EnableRaisingEvents = true;
               while (true) { }
           }
       }

       public static void WriteStuff()
       {
           while (true)
           {
               Thread.Sleep(500);
               using (StreamWriter sw = new StreamWriter(Path.Combine(Environment.CurrentDirectory, "stuff.txt")))
               {
                   sw.WriteLine("stuff", true);
               }
           }
       }
   }
}

The thought process

We need to do 2 things, which means 2 methods (unless you want to break the SRP):

  1. One will notify as when the change happens.
  2. The other one will act upon a file we are going to watch, which will trigger the notification.

The great advantage of .NET Core is that we can use multiple cores so easily. We don’t have to write two separate applications (we probably would, if we considered this for some more serious purpose). This is achieved by using Parallel.Invoke() and passing in actions we want to do. This method doesn’t care about the order you pass the actions in. They will not go off one by one, but kind of randomly, so keep that in mind.