I've a code alike
void ExecuteTraced(Action a, string message)
{
TraceOpStart(message);
a();
TraceOpEnd(message);
}
The callback (a) could call ExecuteTraced again, and, in some cases, asynchronously (via ThreadPool, BeginInvoke, PLINQ etc, so I've no ability to explicitly mark operation scope). I want to trace all operation nested (even if they perform asynchronously). So, I need the ability to get last traced operation inside logical call context (there may be a lot of concurrent threads, so it's impossible to use lastTraced static field).
There're CallContext.LogicalGetData and CallContext.LogicalSetData, but unfortunately, LogicalCallContext propagates changes back to the parent context as EndInvoke() called. Even worse, this may occure at any moment if EndInvoke() was called async.
http://stackoverflow.com/questions/883486/endinvoke-changes-current-callcontext-why
Also, there is Trace.CorrelationManager, but it based on CallContext and have all the same troubles.
There's a workaround: use the CallContext.HostContext property which does not propagates back as async operation ended. Also, it does'nt clone, so the value should be immutable - not a problem. Though, it's used by HttpContext and so, workaround is not usable in Asp.Net apps.
The only way I see is to wrap HostContext (if not mine) or entire LogicalCallContext into dynamic and dispatch all calls beside last traced operation.
Help, please!