在同一线程的多个并行任务中使用Activity.Current是否安全?
关于
Activity.Current在并行任务中行为的疑问 在实现W3C追踪时,我需要用到Activity.Current.SpanId这类变量,由此产生了以下疑问:
官方文档对静态属性Activity.Current的说明如下:
获取或设置当前线程的当前操作(Activity),该属性可跨异步调用流动。
- 该如何结合“当前线程”来理解“跨异步调用流动”?
- 在多个工作任务内执行
using workActivity = new Activity($"Work {id}").Start()时,即便多个任务运行在同一线程池线程上,Activity.Current是否始终能返回对应的Activity实例? Activity.Current属于线程上下文还是任务上下文?它如何能始终为每个并行任务返回正确值?- 我编写了小范围测试代码,结果符合预期,但想确认:
Activity.Current是否始终能安全地从并行任务中访问?
测试代码如下:
using System.Diagnostics; namespace DummyConsoleApp { internal class Program { static void PrintTraceInfo(string msg, int? workerId = null) { Debug.Assert(Activity.Current != null, "Activity.Current != null"); Console.WriteLine($"Worker {workerId} on thread {Thread.CurrentThread.ManagedThreadId} with trace {Activity.Current.TraceId} {Activity.Current.ParentSpanId} --> {Activity.Current.SpanId}: {msg}\n"); } static async Task Work(int id) { using var workActivity = new Activity($"Work {id}").Start(); PrintTraceInfo("Work started", id); await Task.Delay(3000); PrintTraceInfo("Work ended", id); } static async Task Main(string[] args) { using var activity = new Activity("Main").Start(); PrintTraceInfo("Main started."); var tasks = new List<Task>(); for (int i = 0; i < 100; i++) { var id = i; var task = Task.Run(() => Work(id)); tasks.Add(task); } await Task.WhenAll(tasks).ConfigureAwait(false); PrintTraceInfo("Main ended."); } } }
测试结果显示,即便任务在同一线程运行也能输出各自的ID,但这只是小范围测试,我需要更权威的确认。
内容的提问来源于stack exchange,提问作者Joerg
相关产品推荐
相关产品推荐

