Dev Drive and Dotnet Tools

I recently tried out Dev Drive of Windows 11, where a ReFS partition can be created for your code and packages. It went smoothly and most of my projects were built successfully until it came to my Monogame project.

For your context, Monogame is a game engine written in .NET and allows you to write your game entirely in C#. It has a content pipeline to convert your audio and images assets to certain format, and the pipeline is written as local dotnet tools.

Turns out dotnet tools stop working after I moved Nuget package cache folder to the Dev Drive (with NUGET_PACKAGES environment variable). I tried to trigger the tool manually, but the error message is confusing an unhelpful:

I tried to check my Dev Drive and I can see dotnet-mgcb had been restored correctly. Looking a bit further, I realized that .NET is still trying to look for the tool in the old path in %userprofile%\.nuget (even after computer restart).

I might have guessed the issue by now: there must be a cache somewhere pointing to the old paths. Turned out local dotnet tools cache the package information (including the path) in %userprofile%\.dotnet\toolResolverCache.

The fix is obvious now:

  1. Empty %userprofile%\.dotnet\toolResolverCache
  2. Run dotnet tool restore again and double check toolResolverCache to ensure the files are recreated.

I think ideally, since dotnet tool restore can already get the package to the new cache folder in Dev Drive, it should also try to update this toolResolverCache folder automatically instead of requiring a manual wipe like this.

Async void is not the only way to fire and forget

I have developed several apps for Windows 8 and Windows Phone 8, and I am always amazed my one new feature that was introduced to the C# compiler: async and await.

If you are not familiar with the new async feature of C#, you could try to search for “C# async programming” on the Internet or go to this page on MSDN to read the documentation:

If you have already used async/await for a while, you must be aware of the danger of async void (aka “fire-and-forget”), which could creates unobserved exception easily. In other words, you cannot simply use a try-catch block to catch the exception if you are awaiting an async void. There are already many blog posts and videos on this topic already, so I will not describe it again here. You can have a look at this video if you want to know more about the problem of async void:

Continue reading about another culplits: Task.WhenAny →