Skip to content

Instantly share code, notes, and snippets.

@i3arnon
Last active August 29, 2015 14:15
Show Gist options
  • Save i3arnon/06f4c84711c88f6ce04b to your computer and use it in GitHub Desktop.
Save i3arnon/06f4c84711c88f6ce04b to your computer and use it in GitHub Desktop.
LogicalOperationStack (purely hypothetical)
public static class MyStack
{
private static Stack CurrentContext
{
get
{
return Trace.CorrelationManager.LogicalOperationStack;
}
}
public static IDisposable Push(string context)
{
CloneAndSetStack();
Trace.CorrelationManager.StartLogicalOperation(context);
return new PopWhenDisposed();
}
private static void CloneAndSetStack()
{
CallContext.LogicalSetData("System.Diagnostics.Trace.CorrelationManagerSlot", CurrentContext.Clone());
}
private static void Pop()
{
Trace.CorrelationManager.StopLogicalOperation();
}
private sealed class PopWhenDisposed : IDisposable
{
private bool disposed;
public void Dispose()
{
if (disposed)
return;
Pop();
disposed = true;
}
}
public static string CurrentStack
{
get
{
return string.Join(" ", CurrentContext.Cast<string>().Reverse());
}
}
}
@i3arnon
Copy link
Author

i3arnon commented Feb 17, 2015

StartLogicalOperation updates the underlying Stack i.e. the parent context's Stack since no copy has happened yet to the new child context.
CloneAndSetStack generates the copy-on-write that StartLogicalOperation doesn't.

@drowa
Copy link

drowa commented Feb 19, 2015

Just so you know, it is not necessary to change "System.Diagnostics.Trace.CorrelationManagerSlot". To trigger the copy-on-write, you just need to touch any item in the context. You could have something like that to avoid unnecessary allocations:

private static readonly object Flag = new object();
...
CallContext.LogicalSetData("Flag7645", Flag);
Trace.CorrelationManager.StartLogicalOperation(operationId);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment