The Stuff in .NET 11 That I Think is Interesting

by DeeDee Walsh, on Sep 9, 2026, 5:54:27 PM

The real headline of .NET 11 is that the runtime, language, and SDK teams have quietly shipped some of the most pragmatic, blue-collar plumbing fixes in years.

Here's the good stuff hidden under the hood and why it matters to engineers in the trenches.

1. The Container Trench Wars: Linux DNS, Signals, and Crash Dumps

Microsoft's told us for a decade that .NET is cross-platform. And it is. But anyone who's lived through deploying high-throughput, latency-sensitive microservices onto Linux containers knows there's always been a subtle asterisk: cross-platform until you hit the weird edge cases of the Linux kernel and container runtimes.

.NET 11 RC 1 addresses several dark-corner papercuts that platform engineers have spent years duct-taping.

Native DNS Record Resolution on Linux

If you run containerized microservices in dynamic Kubernetes topologies, you've likely suffered through DNS latency spikes, stale resolver caches, or glibc versus musl (Alpine) DNS idiosyncrasies.

When .NET applications rely on standard socket lookups, diagnosing whether a stalled outbound HTTP call was caused by an upstream service or an Alpine Linux DNS timeout has historically been an exercise in hair-pulling. Native Linux DNS record resolution gives teams granular, deterministic control over query strategies and TTL behavior right inside the runtime libraries bypassing brittle OS-level resolver quirks without forcing you to bolt on third-party native wrappers.

In-Process Crash Reporting on Unix

Here's a classic container failure scenario: your service hits an unmanaged memory violation or an unrecoverable runtime crash. In a traditional VM, you might count on createdump to write a multi-gigabyte memory dump to disk.

Inside a hardened, resource-constrained container pod, three things usually happen instead:

  1. Writing the core dump instantly trips the pod’s ephemeral storage or memory quota, triggering an immediate orchestrator eviction.
  2. The orchestrator kills the pod before the dump utility finishes attaching.
  3. The pod restarts silently, leaving behind an exit code 137 or 139 and zero actionable telemetry in your log aggregator.

In-process crash reporting on Unix brings lightweight, post-mortem diagnostic capture directly into the runtime’s execution context. When things go catastrophically wrong, you get structured, actionable crash context printed to standard error or captured in telemetry before the container engine pulls the plug.

[CrashReport] Unhandled Fatal Exception: SIGSEGV (Address: 0x00007f9b4c00) Thread ID: 0x2b4a (Worker-Execution-Queue) Native Frame: libcoreclr.so!DispatchHardwareException + 0x6a Managed Frame: DataPipeline.Engine.ProcessBatch(Span`1 buffer) + 0x112 Exit Reason: Segmentation fault captured in-process before orchestrator SIGKILL. 

Signal Handling & Process Inspection

For years, Windows-based process management in .NET was rich and communicative, while Unix process supervision was a black box of numeric exit codes.

With modern orchestrators, graceful pod termination relies entirely on catching SIGTERM, flushing inflight transactional queues, completing active database operations, and exiting cleanly before the orchestrator loses patience and issues a ruthless SIGKILL. The new process signaling and termination inspection APIs finally let orchestrators and parent watchdogs inspect why a child worker stopped, distinguishing a graceful shutdown from an OS kill signal without parsing exit codes like it's 1988.

2. The Architectural Exorcism: Unions + Closed Polymorphic JSON

Every enterprise codebase over five years old has a dark corner dedicated to the Gang of Four.

It’s usually an elaborate hierarchy of abstract classes, visitor patterns, custom type markers, and 400 lines of brittle System.Text.Json converter boilerplate written by a lead architect who left the company in 2017. All of it exists just to represent a simple domain reality: an operation either Succeeded, Failed with a Validation Error, or Timed Out.

C#

 // The classic enterprise gymnastics: an open hierarchy just to serialize state
public abstract class OperationResultBase { public string Type { get; set; } }
public class SuccessResult : OperationResultBase { public string Payload { get; set; } }
public class ErrorResult : OperationResultBase { public string ReasonCode { get; set; } }


In .NET 11, the combination of C# 15 unions and System.Text.Json closed-type polymorphism acts like an architectural exorcism. 

C#

 // Clean, finite domain modeling:
public union TransactionStatus
{
    Approved(string AuthorizationCode, decimal SettledAmount),
    Declined(string DeclineReason, bool IsRetryable),
    PendingReview(string CaseId)
}


Instead of relying on open polymorphism where any rogue class in your assembly can inherit from a base type and blow up your pattern matching, closed polymorphism guarantees to the compiler and the serializer that the universe of types is fixed and known at build time.

Why Your Security & Performance Teams Will Care:

  1. The End of $type Discriminator Exploits: Open polymorphic deserializers have historically been a frequent source of remote code execution vulnerabilities when attackers inject unexpected assembly types into payload discriminators. Closed-type polymorphism seals the boundary entirely.
  2. Zero Reflection Overhead: Because the set of possible variants is fully known at compile time, the serializer generates direct, optimized branch tables. No dynamic runtime reflection, no custom converters, and zero payload bloating.
  3. Exhaustive State Machines: If you add a new state (e.g., Escalated), the C# compiler immediately flags every unhandled switch across your entire solution before you ever push code to staging.

3. The CI/CD Bill Slash: Tooling That Stops Stealing Your Budget

Developers love to argue for three days in a pull request about whether an allocation inside a low-frequency method costs 40 bytes of garbage collection overhead. Meanwhile, that same PR runs on a self-hosted CI/CD runner that burns twelve minutes re-evaluating dependencies and re-uploading identical multi-gigabyte layers to an Azure Container Registry.

The biggest return on investment in .NET 11 isn't in your runtime code; it’s in your CI pipeline.

Tooling Upgrade

The Pain in Previous Versions

The .NET 11 RC 1 Fix

SDK Container Publishing

Re-pushed gigabytes of unchanged application layers on every minor commit.

Digest-aware layer matching: Skips redundant layer uploads automatically during native SDK publishing.

dotnet pack

In large 50+ project solutions, each pack command triggered repeated, expensive project graph evaluations.

Reuses evaluation graphs: Drastically shortens multi-package artifact generation in enterprise monorepos.

Native MSBuild tar Tasks

Cross-platform build scripts shelled out to external CLI tools (tar, 7z, or bash scripts) to package Linux artifacts.

Built-in archive tasks: Native tar creation directly within MSBuild targets with consistent permissions handling.

 

If you're maintaining an enterprise repository with dozens of projects, upgrading your build runners to the .NET 11 SDK noticeably drops build-agent compute minutes on day one without you having to refactor a single line of business logic.

4. The Immortal Cockroach: Windows Forms Kiosk Mode

If you spend all your time reading developer social media, you’d be forgiven for believing that the entire global economy runs on Next.js, WebAssembly, and edge workers.

But here's my view: The physical world runs on Windows Forms.

The baggage drop scales at major international airports, the touchscreens controlling CNC milling machines, the automated blood analysis instruments in clinics, and the retail point-of-sale systems at your local lumber yard are almost all WinForms applications. They were built fifteen years ago, they run twenty-four hours a day, and businesses won't rewrite them in Electron or modern web frameworks because those systems require stability, direct serial/hardware communication, and near-zero idle memory footprint.

In .NET 11, Microsoft did something refreshingly pragmatic: they shipped dedicated Kiosk-style experience management and modern visual styles for Windows Forms.

Instead of developers writing crappy Win32 API interop calls to intercept keyboard hooks, block Alt+Tab, hide Windows taskbars, and suppress system dialogs on unattended devices, the framework now provides built-in, native kiosk lifecycle control.

 // Bringing dedicated, modern kiosk controls to appliances that run the real world
ApplicationConfiguration.Initialize();

var kioskWindow = new Form
{
    Text = "Warehouse Station #14",
    WindowState = FormWindowState.Maximized,
    FormBorderStyle = FormBorderStyle.None
};

// Built-in device lockdown without unmanaged Win32 window hooking hacks
kioskWindow.EnableKioskMode(new KioskOptions
{
    SuppressSystemGestures = true,
    PreventTaskSwitching = true,
    RestrictEdgeSwipes = true
});

Application.Run(kioskWindow);

 

Giving WinForms first-class kiosk primitives is an acknowledgment of reality. Enterprise software has a thirty-year lifespan, and respecting the utility software that powers supply chains is good engineering.

The Verdict: Blue-Collar Software Wins

The defining characteristic of .NET 11 is engineering maturity. It polishes the rough edges of cloud-native Linux runtimes, streamlines data modeling by retiring obsolete OOP rituals, speeds up deployment pipelines, and continues supporting the mission-critical systems that keep the lights on.

Install the release candidate, skip the syntax tutorials, and try running it where software actually lives: under load, inside containers, and on the factory floor.

Topics:.NET.NET 11

Comments

Subscribe to GAPVelocity AI Modernization Blog

FREE CODE ASSESSMENT TOOL