While profiling our application’s performance we stumbled upon a surprising contention point inside System.Threading.Timer
(I say surprising as System.Threading.Timer
is the more appropriate timer for multi-threaded environments out of the available timers)
This can be demonstrated by executing the following piece of code:
Back in the olden days of .NET 4.0 we didn’t have Task.Run
. All we had to start a task was the complicated Task.Factory.StartNew
. Among its parameters there’s a TaskCreationOptions
often used to specify TaskCreationOptions.LongRunning
. That flag gives TPL a hint that the task you’re about to execute will be longer than usual.
Nowadays with .NET 4.5 and above we mostly use the simpler and safer Task.Run
but it isn’t uncommon to wonder how do you pass TaskCreationOptions.LongRunning
as a parameter like we used to do with Task.Factory.StartNew
.
Trace.CorrelationManager.LogicalOperationStack
enables having nested logical operation identifiers where the most common case is logging (NDC). Evidently it doesn’t work with async/await.