Summary
Activity.Current can be lost when switching threads in Visual Studio's async model, particularly when using JoinableTaskFactory. Add helpers to properly flow tracing context across async boundaries.
Problem
using (VsixTelemetry.StartActivity("ParentOperation"))
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// Activity.Current may be null here!
using (VsixTelemetry.StartActivity("ChildOperation"))
{
// This span won't be linked to parent
}
}
Proposed Solution
// Option 1: Extension method for JoinableTaskFactory
await ThreadHelper.JoinableTaskFactory
.WithActivityContext()
.SwitchToMainThreadAsync();
// Option 2: Wrapper that captures and restores context
using (VsixTelemetry.PreserveContext())
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// Activity.Current is preserved
}
// Option 3: Run with explicit context
await VsixTelemetry.RunWithContextAsync(async () =>
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// Context flows correctly
});
Implementation Notes
- Capture
Activity.Current before thread switch
- Restore it after the switch using
Activity.SetCurrent()
- Consider using
AsyncLocal<T> for automatic propagation
- Test with various VS async patterns
Summary
Activity.Currentcan be lost when switching threads in Visual Studio's async model, particularly when usingJoinableTaskFactory. Add helpers to properly flow tracing context across async boundaries.Problem
Proposed Solution
Implementation Notes
Activity.Currentbefore thread switchActivity.SetCurrent()AsyncLocal<T>for automatic propagation