For small chunks of compute-bound work that must be offloaded to the background, you can choose from several APIs and patterns in .NET. In code written before .NET 4.0, you would probably use ThreadPool.QueueUserWorkItem. In modern day apps, you might…
The battle of async methods
In a contest between async proper, Task.Run, and dedicated threads, who will win? Let’s gather some data points for a specific scenario and find out! Today’s benchmark will make use of a trivial single process WCF named pipes application using…
SSD and … sync I/O?
Walter Bright (via Andrei Alexandrescu) says, “Measuring gives you a leg up on experts who are too good to measure.” Today I’ll present some measurements that might be a bit surprising. In the old days of mechanical spinning disks, the…
Orchestrating race conditions
Many a programmer has struggled with unit tests and those pesky race conditions that are seemingly immune to them. Is it even possible to verify concurrency correctness using TDD? I am going to tell you that it is — sometimes.…
Laziness is a virtue
Sometimes you want lazy initialization but your initialization function is asynchronous. Stephen Toub wrote about this conundrum years ago on the pfxteam blog. The solution as he describes it is fairly straightforward — use Lazy<T> combined with Task<T> and you’re…
Native InputQueue thread-safety
In the previous post, I introduced my port of InputQueue to C++. As usual, the unit tests drove the creation of a correct single-threaded implementation but slightly more needed to be done to make the code thread-safe. The go-to construct…
InputQueue, the non-BlockingCollection
The .NET 4.0+ solution to the producer-consumer problem is BlockingCollection. A sample app with a single producer and consumer using an ordered queue of integers would look something like this: This is simple enough, but the problem is that DequeueLoop.…
Threads don’t scale
Async aficionados should know by now that I/O-bound workloads based on dedicated threads simply do not scale past a certain limit. Typically, when you start creating more threads than you have logical CPU cores, you will suffer ever-increasing overhead due…
Async fixed concurrency workflows
In the previous post, I mentioned async fixed concurrency workflows as providing the best balance between resource utilization, latency, and throughput. Let’s explore two ways to build such a workflow. Single-threaded workflow The first design we will look at involves…
Designing for fixed concurrency
Consider a simple load test which is trying to maintain a constant stream of parallel requests against a server. That is, at any given moment the server should be handling, say, 100 concurrent requests. The exact number is not important,…