These weird tricks will make your life easier with multithreading in C#. In my experience, a lot of developers are not aware of them.
It has been called the best library you’re not using. Perhaps because it’s not included by default in .NET, you have to install the
System.Threading.Tasks.Dataflow NuGet package.
This library is a hidden gem that allows you to define data processing pipelines with stages for processing, buffering and grouping while taking care of concurrency and error handling. You can, for example, define a pipeline that receives data from multiple sources and batches inserts to a database to improve performance. Head to the documentation and discover the power of Dataflow.
Wrapping legacy asynchronous patterns
Once upon a time, you started
new Thread()s, and life was full of pain.
.NET Framework evolved, and we had the Asynchronous Programming Model (APM) in .NET Framework 1.0, then Event-based Asynchronous Pattern (EAP) in .NET Framework 2.0, and Task-based Asynchronous Pattern (TAP) in .NET Framework 4.
Today it makes no sense to use anything other than TAP and async/await, but sometimes you have to work with legacy code that still uses the old patterns (I’m looking at you, RabbitMQ).
The good news is that you can wrap those with TAP, and the .NET documentation describes some patterns to do it. If you find yourself dealing with IAsyncResults or Events, do yourself a favor and wrap them with TAP.
Don’t forget the Parallel class and PLINQ
The Parallel class together with Parallel LINQ (PLINQ) are easy ways to add data parallelism to an application, allowing you to process collections concurrently while being able to specify how many threads you want, how to partition the data and which scheduler to use. It doesn’t get simpler than these.
Not really weird or hidden, but still overlooked a lot of times. I forget about them sometimes. Perhaps because this is multithreading after all, so it can’t possibly be that easy.