Mert Özen Further With Every Line

Blog

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

Series
17 posts found #async
C# Async and .NET 9–10: Task.WhenEach, the Lock Type and Async LINQ in the Framework
Backend PART 17

C# Async and .NET 9–10: Task.WhenEach, the Lock Type and Async LINQ in the Framework

The .NET 9 Task.WhenEach that replaces the WhenAny loop and how it handles failed tasks, System.Threading.Lock recognized by the C# 13 lock statement and its limits (CS9216, CS1996, CS4007, CS9202), async LINQ moving into the framework in .NET 10, async Select, and fixing the clash with the System.Linq.Async package.

7 Nov 2026 11 min 6
C# Async and .NET 8: TimeProvider, ConfigureAwaitOptions, Parallel.ForAsync and CancelAsync
Backend PART 16

C# Async and .NET 8: TimeProvider, ConfigureAwaitOptions, Parallel.ForAsync and CancelAsync

On .NET 6 we wrote our own IClock; on .NET 8, TimeProvider and FakeTimeProvider make a 15-minute wait take 0 ms in a test. SuppressThrowing, which waits without throwing, and its Task<T> trap, ForceYielding, Parallel.ForAsync, which takes an index range directly, and CancelAsync, which runs callbacks without blocking the caller.

7 Nov 2026 10 min 7
C# Timers and Waiting: PeriodicTimer, WaitAsync and Task.Delay
Backend PART 15

C# Timers and Waiting: PeriodicTimer, WaitAsync and Task.Delay

Overlapping callbacks in System.Threading.Timer, overlap-free periodic work with .NET 6 PeriodicTimer, how Thread.Sleep and Task.Delay affect the thread pool and how precise Task.Delay is, System.Timers.Timer swallowing exceptions, WaitAsync not canceling the operation, retries with backoff and jitter, and a timer collected by the GC.

7 Nov 2026 10 min 8
Producer/Consumer with C# Channels: Backpressure, Bounded Channels and Pipelines
Backend PART 14

Producer/Consumer with C# Channels: Backpressure, Bounded Channels and Pipelines

An async queue with System.Threading.Channels: why three orders fit into a channel with a capacity of two, Writer/Reader and Complete, the WaitToReadAsync/TryRead loop, FullMode options and itemDropped on bounded channels, multiple consumers, an order pipeline that passes failures on with Complete(ex), and the cost of forgetting Complete.

7 Nov 2026 9 min 7
C# Synchronization: lock, Interlocked, SemaphoreSlim and Concurrent Collections
Backend PART 13

C# Synchronization: lock, Interlocked, SemaphoreSlim and Concurrent Collections

Why sold++ never reaches a million: race conditions and the check-then-act race. The rules of lock and why you can't await inside it, atomic counters and CompareExchange with Interlocked, the SemaphoreSlim pattern for an async cache, ConcurrentDictionary factories that run more than once and the Lazy<T> fix.

7 Nov 2026 11 min 7
C# Parallelism: Parallel.For, Parallel.ForEachAsync, PLINQ and When to Use Task.Run
Backend PART 12

C# Parallelism: Parallel.For, Parallel.ForEachAsync, PLINQ and When to Use Task.Run

Why nothing finishes when you pass an async lambda to Parallel.ForEach, concurrency versus parallelism, Parallel.For and thread-local aggregation, bounded concurrency with .NET 6 Parallel.ForEachAsync, ordering in PLINQ, BenchmarkDotNet on when parallelism pays off and when it costs you, and where Task.Run belongs.

7 Nov 2026 15 min 5
C# IAsyncEnumerable, await foreach and Async Dispose
Backend PART 11

C# IAsyncEnumerable, await foreach and Async Dispose

Collecting books from a paged API with Task<List<T>> leaves the first element until last; with an async iterator, yield return and await together let the first page flow right away. What await foreach expands to and MoveNextAsync's ValueTask, EnumeratorCancellation and CS8425, the finally that runs on break, IAsyncDisposable and await using, DeserializeAsyncEnumerable and streaming in ASP.NET Core.

7 Nov 2026 9 min 4
C# ValueTask: When to Use It Instead of Task, and Its Rules
Backend PART 10

C# ValueTask: When to Use It Instead of Task, and Its Rules

An async method that returns synchronously from a cache allocates 72 bytes per call with Task<int>, and nothing with ValueTask<int>. The Debug versus Release measurement gap, the runtime's small-result cache, the cached and truly asynchronous paths in BenchmarkDotNet, the real InvalidOperationException from awaiting a ValueTask twice on a Channel, AsTask, and when to choose ValueTask.

7 Nov 2026 9 min 6
C# async void and Fire-and-Forget: Lost Exceptions
Backend PART 09

C# async void and Fire-and-Forget: Lost Exceptions

Why an exception from an async void method crashes the process without ever reaching try/catch, and how async Task fixes it. Using async void correctly in event handlers, hidden async void with List.ForEach, the silently lost failure of an un-awaited task and UnobservedTaskException, the CS4014 warning, a safe Forget extension that logs the failure, and the scope trap in ASP.NET Core.

7 Nov 2026 8 min 4
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 4
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 2
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 7
Blog Map