Mert Özen Further With Every Line

Blog

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

Series
228 posts found #dotnet
Events in C#: EventHandler, Safe Raising and Subscription Leaks
Backend PART 03

Events in C#: EventHandler, Safe Raising and Subscription Leaks

How the event keyword protects a delegate and CS0070, the private field and add/remove methods the compiler generates, the EventHandler convention and records as event data, safe raising with ?.Invoke, custom add/remove accessors and CS0079, a 50 MB subscription leak measured with WeakReference, and a Subscribe method that returns IDisposable.

7 Nov 2026 10 min 14
Lambdas and Closures in C#: The Captured Variable Trap
Backend PART 02

Lambdas and Closures in C#: The Captured Variable Trap

Lambda shapes and the C# 10 explicit return type, a closure capturing the variable rather than its value, seeing the compiler-generated display class with reflection, the captured for loop variable and the C# 5 foreach change, measuring 88 bytes of allocation per closure, static lambdas and CS8820, and the capture bug that meets deferred LINQ.

7 Nov 2026 9 min 9
Delegates, Func and Action in C#: Passing Methods Around as Values
Backend PART 01

Delegates, Func and Action in C#: Passing Methods Around as Values

A delegate is a type that holds a method: a class deriving from MulticastDelegate, Method and Target, Func/Action/Predicate, the natural type of lambdas in C# 10 and CS8917, passing methods as parameters, the last result of a multicast delegate and the broken chain, converting between delegate types and variance, and the traps of null delegates and lambdas that -= won't remove.

7 Nov 2026 9 min 13
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 8
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 10
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 10
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 9
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 9
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 8
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 6
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 8
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 6
Blog Map