Scaling ASP.NET Core Minimal API Responses

I have been running an ASP.NET Core application on Raspberry Pi Zero 2W. In an early performance test, I have deployed an application with two endpoints: / and /data. These endpoints return a simple string response as shown below.

app.MapGet("/", () =>
{
    return "Hello World";
});

app.MapGet("/data", (HttpContext ctx) =>
{
    ctx.Response.StatusCode = 200;
    var buffer = ctx.Response.BodyWriter.GetSpan(11);
    "Hello World"u8.CopyTo(buffer);
    ctx.Response.BodyWriter.Advance(11);
});

The application is compiled for .NET 9, without enabling native AOT. I have measured the performance of these APIs using CHttp tool.

CHttp is a simple tool to test performance of HTTP endpoints.

Find out more


IAsyncEnumerable WithCancellation

I recently used IAsyncEnumerable in C# the first time. In this post, I will summarize some of my learnings based on .NET 9.

There is an excellent introduction to Iterating with Async Enumerables that introduces they key concepts from the iterators point of view and then details the internals of an async enumerator.

Key Concepts

IAsync­Enumerable<T> allows creating iterators that produce elements in an asynchronous fashion. Although it has been around for a few years, it is not commonly seen in application source code. Typically, iteration happens over a collection where elements are already computed, making synchronous iteration adequate, like iterating a list of integers. There are also cases where the elements of an iterator can computed synchronously, for example the runtime provides Enumerble.Range or Enumerable.Repeat iterators. Additionally, Select extension can project each element of a sequence into a new shape, like a Task<T>, then a consumer awaits these tasks to complete concurrently.

Find out more


HTTP2 Huffman Decoding

Introduction

HTTP2 headers can contain string literals that are Huffman encoded for compression. Before processing these headers, servers must first decode them according to RFC 7541.

A string literal in a header consists of three components:

  • A single bit flag indicating Huffman encoding

  • The length of the encoded data

  • The encoded data itself

Find out more


Notes on Code Coverage for .NET Applications

This post summarizes my learnings about code coverage visualization in SonarQube and GitLab.

Formats for GitLab and SonarQube

I'll detail different options for displaying code coverage for a C# (.NET) application in both tools. GitLab uses Cobertura coverage files. When such a file is uploaded as a job artifact, GitLab marks each line as covered or uncovered in a pull request (Merge Request in GitLab terms). GitLab also provides other coverage features that are not covered in this post.

SonarQube accepts several coverage formats. As of writing this post, for .NET applications it works with coverage files in these formats:

Find out more


Getting Started with ClrMD

What is ClrMD?

ClrMD or Microsoft.Diagnostics.Runtime NuGet package is a helpful tool to analyze crash dumps or debug applications at runtime.

This post discusses scenarios where this tool excels compared to other diagnostic tools. Its capabilities are comparable to WinDBG with the SOS extension or PerfView. As a NuGet package, it also provides common CLR abstractions enabling developers to build their own diagnostic tools.

In most investigations, the usual tools such as WinDBG + SOS, PerfView, Visual Studio's performance profiler, etc. provide clear insights into the application. However, in rare cases, a developer might want to write custom scripts or code for deeper analysis not available through standard commands or views. In these cases, ClrMD comes to the rescue.

Find out more