The pain of serializing unions and closed class hierarchies with System.Text.Json: Exploring the .NET 11 preview - Part 7
In this post I discuss the System.Text.Json support for unions and closed hierarchies coming in .NET 11, the decisions made, and some of the sharp edges I hit
How Uno Platform uses .NET, MCP, and AI to build high quality apps
<p>How Uno Platform built two Model Context Protocol servers in C# so AI agents can ground themselves in real documentation and then see and drive a running cross-platform .NET app.</p> <p>The post <a href="https://devblogs.microsoft.com/dotnet/how-uno-platform-uses-dotnet-mcp-ai-to-build-high-quality-apps/">How Uno Platform uses .NET, MCP, and AI to build high quality apps</a> appeared first on <a href="https://devblogs.microsoft.com/dotnet">.NET Blog</a>.</p>
Debugging my new network, when 10 Gigabit Ethernet Runs at 300 Megabits
<div><p>I've been moving my home storage over to a UniFi UNAS Pro 8 as <a href="/blog/migrating-a-synology-nas-to-a-unifi-unas-pro-8-with-robocopy-smb-multichannel-and-surprising-performance-traps">part of a larger homelab moderization</a>. My main IRONHEART (the ultimate PC from a few years back) desktop now has an Intel E610-XT2 10GbE card, the NAS is on 10GbE, and there's a Minisforum MS-01 miniPC on the same network with a 10GbE SFP+ connection running Immich and Portainer and a few other things.</p> <p>Everything says 10 gigabit. Windows says 10 gigabit. UniFi says 10 gigabit. SMB copies are using the correct NIC but my file copies are running at around <strong>100 to 200 megabits per second which is sad making.</strong></p> <p>Naturally, I blamed the NAS, and the spinning rust within. The UNAS has six 16 TB spinning disks in RAID 6 and a pair of NVMe SSDs being used as cache. I'm also running Immich on the MS-01, with its photo library living on the UNAS, so there are lots of thumbnails, metadata reads, and little background writes happening. All seem like reasonable suspects.</p> <p>I switched the UNAS SSD cache from read-write to read-only. No meaningful difference. I stopped Immich completely. No difference. I looked at <code>iostat</code>; the disks weren't saturated. We looked at SMB signing and Windows Defender network scanning. Still slow.</p> <p>Then I stopped testing the NAS and ran <code>iperf3</code> directly between the Windows desktop and the MS-01:</p> <pre><code>iperf3 -c 192.168.1.222 -P 4</code></pre> <p><strong>133 Mbit/sec</strong></p> <p>Oops. The reverse test was better, but still wrong:</p> <pre><code>iperf3 -c 192.168.1.222 -P 4 -R</code></pre> <p><strong>1.33 Gbit/sec</strong></p> <p>That's weird. Now the disks, SMB, Immich, RAID, and the NAS itself were completely out of the equation. This was a Windows/NIC problem and it's weirdly asymmetrical.</p> <p>Looking at the Intel adapter statistics shows me...</p> <pre><code>Get-NetAdapterStatistics -Name "Ethernet - 10 Gig Intel"</code></pre> <p>There were nearly a million <code>ReceivedDiscardedPackets</code>. During one ten-second <code>iperf3</code> test, the counter increased by another 268. Why?</p> <p>The E610 driver had its receive buffers at the default <strong>512</strong>, although it supported up to 4096. I increased them. I love an increased buffer.</p> <pre><code>Set-NetAdapterAdvancedProperty ` -Name "Ethernet - 10 Gig Intel" ` -DisplayName "Receive Buffers" ` -DisplayValue "4096"</code></pre> <p>The discarded-packet count during the next test went from <strong>268 to zero</strong>, and receive throughput jumped from <strong>1.33 Gbit/sec to 5.15 Gbit/sec</strong>. The transmit direction was still terrible, basically <strong>313 Mbit/sec</strong>. The next experiment was disabling Large Send Offload (LSO) V2 for IPv4:</p> <pre><code>Set-NetAdapterAdvancedProperty ` -Name "Ethernet - 10 Gig Intel" ` -DisplayName "Large Send Offload V2 (IPv4)" ` -DisplayValue "Disabled"</code></pre> <p>Then I ran the same <code>iperf3</code> test again.</p> <p><strong>7.03 Gbit/sec</strong></p> <p>That's not a typo. <strong>313 Mbit/sec to 7.03 Gbit/sec by changing one NIC setting.</strong> Sweet sassy molassey.</p> <p>LSO exists for a good reason: Windows can hand large TCP buffers to the NIC and let the adapter/driver segment them into network-sized packets, reducing CPU work. Microsoft does, however, explicitly point out that segmentation offload can reduce maximum sustainable throughput with some network adapters/configurations. LSO is usually useful, but not in this case.</p> <p>In my particular combination of Windows and the Intel E610-XT2, something in the IPv4 LSO path was very, very sad. I don't yet know whether this is an Intel driver bug, firmware issue, Windows interaction, or something particular to this machine, so I wouldn't turn this into random tech blogger advice that everyone should disable LSO. <strong>Measure first, cut once. Er, twice. Just stay woke.</strong></p> <p>Finally I went back to the test that started all this and copied the same large file to the UNAS and Robocopy reported:</p> <pre><code>Speed : 350,201,354 Bytes/sec. Speed : 20,038.682 MegaBytes/min.</code></pre> <p>About <strong>350 MB/sec</strong>, or <strong>2.8 Gbit/sec of sustained real-world SMB writes</strong> to a six-disk RAID 6 NAS.</p> <p>That's much more like it. The useful lesson isn't "disable LSO." It was that when storage is mysteriously slow, eventually you have to stop testing storage. <code>iperf3</code> removed the NAS, filesystem, RAID, cache, SMB and disks from the experiment in one move. Once the raw network was also slow, the problem became dramatically smaller. And, sometimes the little checkbox labeled <strong>Large Send Offload</strong> is capable of making your 10 gigabit card run like it's 2004.</p> <p>TL;DR - with LSO V2 for IPv4 enabled, Windows-to-Linux <code>iperf3</code> managed about <strong>313 Mbit/sec</strong>. Turning off that single offload took the exact same test to <strong>7.03 Gbit/sec</strong>. I’m deliberately saying <em>on this machine</em> because LSO is normally useful and this isn’t blanket advice to disable it everywhere. </p><br/><hr/>© 2025 Scott Hanselman. All rights reserved. <br/></div>
.NET Conf 2026 – Save the Date
<p>.NET Conf returns November 10-12, 2026, with three days of sessions, community, and the launch of .NET 11.</p> <p>The post <a href="https://devblogs.microsoft.com/dotnet/dotnet-conf-2026/">.NET Conf 2026 – Save the Date</a> appeared first on <a href="https://devblogs.microsoft.com/dotnet">.NET Blog</a>.</p>
Finding the total number of processors on a machine with .NET
In this post I show how to find the total number of logical CPUs on a host (not just those available to a process); something that isn't exposed in modern .NET
From dotnet run to Foundry Hosted Agent in 3 lines of C#
<p>You built an agent with Microsoft Agent Framework and it works great on your machine. Now what? Turns out deploying it to production takes 1 NuGet package, 3 lines of C#, and 2 commands. Let's do it.</p> <p>The post <a href="https://devblogs.microsoft.com/dotnet/from-dotnet-run-to-foundry-hosted-agent-in-3-lines-of-csharp/">From dotnet run to Foundry Hosted Agent in 3 lines of C#</a> appeared first on <a href="https://devblogs.microsoft.com/dotnet">.NET Blog</a>.</p>
Explore new features available in C# 15 preview
<p>C# 15 ships with .NET 11. It adds union types, closed hierarchies, a preview of the updated unsafe model, and a few smaller changes that remove everyday ceremony.</p> <p>The post <a href="https://devblogs.microsoft.com/dotnet/explore-csharp-15/">Explore new features available in C# 15 preview</a> appeared first on <a href="https://devblogs.microsoft.com/dotnet">.NET Blog</a>.</p>