The .NET platform provides a lot of out-of-the-box synchronization primitives and thread-safe collections. If, while developing an application, you need to implement thread-safe cache or request queue, you'll probably use one or even several of these solutions at a time. Sometimes it can lead to performance issues: lock convoys, excessive memory consumptions, and long garbage collecting processes.
These issues can be solved, if we keep in mind that standard solutions are made to be general and can have overhead that's excessive for our scenarios. So you can write your own thread-safe collection that works well in your situation.
In this talk, we'll explore several cases when using methods from .NET standard library (Task.Delay, SemaphoreSlim, ConcurrentDictionary) led to performance degradation and discuss solutions tailored specifically to certain cases and therefore free of such flaws. We'll also look into .NET internals and explore approaches that are being used there.