A Shared lock Cost the Same as a Private One at One Thread, and Not at Two
On .NET 10.0.12 a shared lock matched a per-thread lock at one thread and cost more from two up, where Monitor.LockContentionCount left zero.

Topics · 6 articles
On .NET 10.0.12 a shared lock matched a per-thread lock at one thread and cost more from two up, where Monitor.LockContentionCount left zero.

On EF Core 10.0.12, AsEnumerable() before Where().Count() sent a full-table SELECT instead of COUNT(*) and allocated 1056.36 KB against 49.53 KB at 1,000 rows.

In a dotnet-dump of a contested lock, clrstack -all marked no thread as the owner. syncblk named it, and a suspended await appeared only in dumpasync.

A thread pool queue held at two thousand work items read 1986 through one provider and -13 through the other, in the same second, in the same process.

Server GC finished 2.7 times faster and collected 17 times less often — and made the slowest request in the run 5 to 13 times slower. Both numbers are real.

Blocking on a task is the case the thread pool compensates for. Blocking on a sleep or an event is the case it cannot see, and it finished 2.5 times slower.
