简体   繁体   English

如何在方法之间传递跟踪 id 而无需在 C# 中作为参数传递?

[英]How to pass a trace id between methods without passing as parameters in C#?

Let's say I have two methods假设我有两种方法

public async Task A()
{
   var traceId = Guid.NewGuid().ToString();
   Log($"{traceId}-Method A was called");
   await B(traceId);
}

public async Task B(string traceId)
{
   Log($"{traceId}-Method B was called");
}

I need to keep a log of the execution path.我需要保留执行路径的日志。 For this I need to pass a trace id but this clutters the code.为此,我需要传递一个跟踪 ID,但这会使代码混乱。 Is there a better way to persist these types of information in C# method calls?有没有更好的方法在 C# 方法调用中保留这些类型的信息?

PS: Method A and B could be in different c# assemblies as well. PS:方法 A 和 B 也可以在不同的 c# 组件中。 This is a web application.这是一个 web 应用程序。

Ideally, you would use a tracing/logging system that already provides this functionality, eg, Activity has an Id .理想情况下,您将使用已经提供此功能的跟踪/日志记录系统,例如Activity有一个Id

But if you want to build your own, you can use AsyncLocal<T> :但是,如果您想构建自己的,可以使用AsyncLocal<T>

private static readonly AsyncLocal<string> traceId = new();

private static IDisposable SetTraceId(string id)
{
  var oldValue = traceId.Value;
  traceId.Value = id;
  return new Disposable(() => traceId.Value = oldValue);
}

public async Task A()
{
  using var _ = SetTraceId(Guid.NewGuid().ToString());
  Log($"{traceId.Value}-Method A was called");
  await B();
}

public async Task B()
{
  Log($"{traceId.Value}-Method B was called");
}

( Disposable is from my Disposables library ) Disposable来自我的Disposables 库

My recommendations for working with AsyncLocal<T> are: 对使用AsyncLocal<T>的建议是:

  1. Always use immutable types for T .始终对T使用不可变类型。 Otherwise the code can get very confusing.否则代码会变得非常混乱。
  2. When setting AsyncLocal<T>.Value , use a disposable like the code above does to reset it.设置AsyncLocal<T>.Value时,使用像上面代码那样的一次性来重置它。 Again, this makes the code less confusing.同样,这使代码不那么混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM