I have a C# webserver which I have been profiling using the StackOverflow miniprofiler. Because it's not an ASP.NET server, but each request was typically executed on its own thread, I rigged the miniprofiler to use ThreadStatic
storage to track all of the profilers of an incoming request from start to finish. This worked well.
Recently we've converted everything to use async/await
, which means continuations after an await
typically don't come back onto the same Thread
and thus the ThreadStatic
storage no longer works.
What's the best way to pass some small piece of data between different ThreadPool
threads in this case? Are there existing SynchronizationContext
implementations that would be useful for something like this?
What's the best way to pass some small piece of data between different ThreadPool threads in this case?
Using the logical call context via the CallContext
class. It exposes two static methods: LogicalSetData
and LogicalGetData
. The call context is stored and marshaled via the ExecutionContext
, which is also in charge of the sync context, etc.
Using this class has two restrictions:
You're limited to the use of .NET 4.5 and above
Logical call context uses copy-on-write semantics, and performs a shallow copy once the data is mutated. This means you should only be using immutable data, as the references may be shared across multiple threads.
One last thing to note is CallContext
is initialized only once you call it. This means that when using it, you're taking on some overhead because of the copy-on-write.
More on that can be found in a post by Stephan Cleary called Implicit Async Context
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With