Microsoft bids adieu to Windows Phone in new emoji

Windows 11 is here and it comes with a new version of Segoe UI Emoji, the font that’s used across the OS to render various emoji from Unicode codepoint sequences to the emoji you see on screen (developers: use Unicode.NET for your emoji needs!). With it, a number of emoji icons have been upgraded to a new look: some to mirror the connotations and semantics of other emoji fonts, others to be less disparaging. But there’s a less welcome surprise too, for those four… maybe five? of us that still remember the ill-fated Windows Phone fondly.

Continue reading

Using SIMD acceleration in rust to create the world’s fastest tac

NeoSmart Technologies’ open source (MIT-licensed), cross-platform tac (written in rust) has been updated to version 2.0 (GitHub link). This is a major release with enormous performance improvements under-the-hood, primarily featuring handwritten SIMD acceleration of the core logic that allows it to process input up to three times faster than its GNU Coreutils counterpart. (For those that aren’t familiar with it, tac is a command-line utility to reverse the contents of a file.)

This release has been a long time in the making. I had the initial idea of utilizing vectorized instructions to speed up the core line ending search logic during the initial development of tac in 2017, but was put off by the complete lack of stabilized SIMD support in rust at the time. In 2019, after attempting to process a few log files – each of which were over 100 GiB – I decided to revisit the subject and implemented a proof-of-concept shortly thereafter… and that’s when things stalled for a number of reasons.

Continue reading

AsyncLock 3.0 for .NET 5.0 Released

An updated version of AsyncLock has just been released on GitHub and Nuget with improved support for reentrancy detection.

AsyncLock is a async/await-native anonymous lock for .NET and .NET Core that allows safely using async/await while holding a lock, for example:

Continue reading

Multi-touch gestures with native touchpad drivers on Linux

Perhaps one of the biggest difficulties in setting up a Linux system for desktop/home use is the fragmentation of the ecosystem, with many different options claiming to get you from point a to somewhere in the vicinity of point b, each with their subtle differences (and at least a few “gotchas” along the way). An easy example: in 2020, you’d think there would be an easy answer to getting a trackpad/touchpad up and running with support for multi-touch gestures at least on par with the experience on Windows and macOS – after all, it’s been 12 years since Apple made multi-touch popular with 2008 MacBook Air.

Continue reading

Scripting in rust with self-interpreting source code

I have a soft spot in my heart for rust and a passionate distrust (that has slowly turned into hatred) for interpreted, loosely typed languages, but it’s hard to deny the convenience of being able to bang out a bash script you can literally just write and run without having to deal with the edit-compile-run loop, let alone create a new project, worry about whether or not you’re going to check it into version control, and everything else that somehow tends to go hand-in-hand with modern strongly typed languages.

A nifty but scarcely known rust feature is that the language parser will ignore a shebang at the start of the source code file, meaning you can install an interpreter that will compile and run your rust code when you execute the .rs file – without losing the ability to compile it normally. cargo-script is one such interpreter, meaning you can cargo install cargo-script then execute your source code (after making it executable, :! chmod +x %) with something like this:

Continue reading

SecureStore: the open secrets container format

It’s been a while since we first released our SecureStore.NET library for C# and ASP.NET developers back in 2017, as a solution for developers looking for an uncomplicated way of safely and securely storing secrets without needing to build and maintain an entire infrastructure catering to that end. Originally built way back in 2015 to support secrets storage in legacy ASP.NET applications, SecureStore.NET has been since updated for ASP.NET Core and UWP desktop application development, and now we’re proud to announce the release of SecureStore 1.0 with multi-platform and cross-framework support, with an updated schema making a few more features possible and official implementations in C#/.NET and Rust.

Continue reading

Adding a Razor Pages ModelBindingProvider in ASP.NET Core

Microsoft’s official documentation on adding custom model binding providers to convert between (typically) a string and a custom type for complex model binding in ASP.NET Core as of .NET Core 3.1 goes something like this:

  • Create an IModelBinder for your class and use [ModelBinder(BinderType = typeof(MyModelEntityBinder)] to decorate each and every binding site, e.g.
    public async Task<IActionResult> OnPost([ModelBinder(BinderType = typeof(MyModelEntityBinder)]) MyModel model), which provides the runtime with the type information it needs to instantiate the model binding provider and convert the input to a model.
  • Optionally create an IModelBinderProvider class and register it with the ASP.NET Core host to provide the type information ahead-of-time (once and for all), so that you can instead use the barebones and much shorter decoration at each model binding site instead:
    public async Task<IActionResult> OnPost([ModelBinder] MyModel model)

The latter is significantly easier on the eyes and far less error prone… but where does the type registration take place? Per the linked documentation, the recommendation is the following in Startup.cs:

Continue reading

A persistent cache for ASP.NET Core

One of the nicest things about ASP.NET Core is the availability of certain singleton models that greatly simplify some very common developer needs. Given that (depending on who you ask) one of the two hardest problems in computing is caching1, it’s extremely helpful that ASP.NET Core ships with several models for caching data, chief of which are IMemoryCache and IDistributedCache, added to an ASP.NET Core application via dependency injection and then available to both the framework and the application itself. Although these two expose almost identical APIs, they differ rather significantly in semantics.2

Continue reading


  1. Although that *probably* refers more to cache coherence rather than simply key-value persistence, to be perfectly frank. 

  2. It is extremely refreshing to see Microsoft adopting the Haskell/Rust approach of using types to express/convey intention and semantics rather than merely shape. 

Compare streams quickly and efficiently in C# and .NET

Have you ever needed to compare the contents of two files (or other streams), and it mattered how quickly you got it done? To be frank, it doesn’t normally come up in the list of things you may need on a daily code-crunching basis, but that rather depends on what kind of programs you tend to write. In our world, let’s just say it’s not an uncommon task.

At a first blush, it would seem to be no harder than comparing two arrays. A pointer reading from each file, compare bytes as you come across them, and bail when things differ. And it would be that easy if you were to use memory-mapped files and let the OS map a file on disk to a range in memory, but that has some drawbacks that may not always be OK depending on what you’re trying to do with the files (or streams) in question. It also requires having a physical path on the filesystem that you can pass in to the kernel, and it unduly burdens the kernel with some not insignificant workloads that aren’t (in practice) subject to the same scheduling and fairness guarantees that user code would be, and they can tend to slow down older machines significantly1.

Continue reading


  1. Especially under Windows 

Easy Window Switcher 1.2.2

Just a quick heads-up: Easy Window Switcher 1.2.2 has just been released and it brings correct hotkey support for the following keyboard layouts:

  • Swedish
  • German Swiss (QWERTZ)
  • International Spanish

Continue reading