Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
228 posts found #dotnet
C# Deadlocks, SynchronizationContext and ConfigureAwait
Backend PART 08

C# Deadlocks, SynchronizationContext and ConfigureAwait

We reproduce the .Result deadlock for real with our own single-threaded SynchronizationContext and stop it with a watchdog. How await captures the context and Posts to it, why it does not hang in a console app or ASP.NET Core but risks thread pool starvation, async all the way, ConfigureAwait(false) in library code, the thread that does not change on a completed task, and the price of wrapping with Task.Run.

7 Nov 2026 9 min 7
C# CancellationToken: Cancellation, Timeouts and Linked Tokens
Backend PART 07

C# CancellationToken: Cancellation, Timeouts and Linked Tokens

Cancellation in .NET is cooperative: a method that takes the token and never checks it does not stop. The roles of CancellationTokenSource and CancellationToken, passing the token down, ThrowIfCancellationRequested in CPU work, the task that ends Faulted when Task.Run does not get the token, CancelAfter and HttpClient.Timeout, telling user cancellation from timeouts with linked tokens, stopping WhenAny's losers, and API design.

7 Nov 2026 9 min 4
Concurrent Work in C# with Task.WhenAll and Task.WhenAny
Backend PART 06

Concurrent Work in C# with Task.WhenAll and Task.WhenAny

Async code is not concurrent by itself: awaiting independent work one by one adds the durations up. Starting first and waiting later, getting ordered results with Task.WhenAll, the trap of starting tasks twice with LINQ Select, WhenAll waiting for everyone after a failure, first answer and timeouts with WhenAny, losers that keep running, and processing tasks as they complete.

7 Nov 2026 9 min 9
Exceptions in C# Async: AggregateException and Errors in WhenAll
Backend PART 05

Exceptions in C# Async: AggregateException and Errors in WhenAll

An exception in an async method goes into the task and is thrown with its original type at the await. Throwing parameter checks at the call, the difference between Wait, GetResult and await, reaching every error and partial results from WhenAll, an error order that differs between two overloads, AggregateException.Handle and unobserved task exceptions.

7 Nov 2026 9 min 7
How C# async/await Works: The State Machine and Continuations
Backend PART 04

How C# async/await Works: The State Machine and Continuations

await does not always wait: on a finished task the code continues on the same thread. What the async keyword actually does, the GetAwaiter/IsCompleted/OnCompleted steps, a working hand-written state machine, looking at the compiler-generated type with reflection (a class in Debug, a struct in Release), which thread runs the continuation, and the awaitable pattern.

7 Nov 2026 10 min 5
C# Task and Task<T>: A Promise That Starts Hot
Backend PART 03

C# Task and Task<T>: A Promise That Starts Hot

An async method starts running the moment it is called; await does not start work, it waits for its result. The task life cycle and Status values, creating tasks with Task.FromResult and TaskCompletionSource, awaiting the same task twice, starting work first and awaiting later, and the Task<Task> trap of Task.Factory.StartNew.

7 Nov 2026 10 min 7
C# Threads and the ThreadPool: A Short History of Async from APM and EAP to TPL
Backend PART 02

C# Threads and the ThreadPool: A Short History of Async from APM and EAP to TPL

Foreground versus background threads, why the Thread class cannot carry results or errors, and a real measurement of 1000 threads against the thread pool. Then .NET's road to async: APM's Begin/End pair, EAP's Completed event, TPL's Task and the async/await that arrived with C# 5.

7 Nov 2026 10 min 6
Why Async Exists in C#: Blocking, I/O and Scale
Backend PART 01

Why Async Exists in C#: Blocking, I/O and Scale

The same 100 stock queries finish in one second with async and in 8-9 seconds with code that blocks the thread. The difference between I/O-bound and CPU-bound work, what blocking costs in a UI and on a server, thread pool starvation, why async buys capacity rather than speed, and the fake async trap.

7 Nov 2026 9 min 12
LINQ and .NET 10: LeftJoin, RightJoin, Shuffle, Sequence and Async LINQ
Backend PART 17

LINQ and .NET 10: LeftJoin, RightJoin, Shuffle, Sequence and Async LINQ

LINQ in .NET 10: LeftJoin and RightJoin replacing the GroupJoin and DefaultIfEmpty pattern, the deferred Shuffle, Sequence and InfiniteSequence built on generic math, System.Linq.AsyncEnumerable in the BCL and the CS0121 clash with the System.Linq.Async package; a short look at FullJoin coming in .NET 11.

7 Nov 2026 10 min 10
LINQ and .NET 9: CountBy, AggregateBy and Index
Backend PART 16

LINQ and .NET 9: CountBy, AggregateBy and Index

LINQ in .NET 9: CountBy, which returns a sequence rather than a dictionary, AggregateBy for per-key accumulation and a BenchmarkDotNet measurement of their memory advantage over GroupBy, Index() instead of Select((x, i) => ...), the Queryable counterparts and the mutable seed trap.

7 Nov 2026 11 min 7
LINQ and .NET 7–8: Order, ToDictionary Without Selectors and Performance
Backend PART 15

LINQ and .NET 7–8: Order, ToDictionary Without Selectors and Performance

.NET 7's Order and OrderDescending, which need no key selector, why a missing IComparable only blows up at runtime, culture-sensitive versus ordinal string sorting, .NET 8's selector-less ToDictionary, and vectorized Max/Sum plus Order versus OrderBy(x => x) measured with BenchmarkDotNet.

7 Nov 2026 10 min 8
LINQ with Real Data: Scenarios on Orders Read from a JSON File
Backend PART 14

LINQ with Real Data: Scenarios on Orders Read from a JSON File

LINQ over orders read from a file with System.Text.Json: the casing trap and JsonSerializerDefaults.Web, validating the data (duplicates, unknown customers, bad quantities), monthly revenue, best sellers, a customer report with GroupJoin, writing JSON back and streaming with DeserializeAsyncEnumerable.

7 Nov 2026 12 min 7
Blog Map