在.NET Core中,我希望支持这样的场景,即将代码包装在某些上下文中,例如:
那些上下文还可以相互嵌套。
调用
然而,我不知道在多线程场景下实现类似行为的最佳方法是什么。
期望的日志应该是这样的:
Method 1 > Method A > A Method 1 > Method B > B
当然,一个任务可以在另一个任务中启动,情况会更加复杂。
还有一件事需要注意: 由于某些遗留原因,我无法在创建LoggingContext时传递所有依赖项,必须采用静态解决方案。
我能想到唯一的想法是在创建新任务时使用ExecutionContext.SupressFlow,并将当前堆栈复制到新的AsyncLocal对象中,但这是一个好的解决方案吗?修改执行上下文似乎对我来说有点不安全。
using(new LoggingContext("Method 1"))
{
}
那些上下文还可以相互嵌套。
using(new LoggingContext("Method 1"))
{
Method2();
}
void Method2()
{
using(new LoggingContext("Method 2"))
{
logger.Log("ERROR")
}
}
调用
logger.Log("ERROR")
后,我希望它能记录传递的消息以及堆栈上下文标识符,例如:
在单线程场景下非常容易 - 它需要一个全局可访问的上下文堆栈。在.NET Core中,例如是一些Method 1 > Method 2 > ERROR
public static AsyncLocal<Stack<LoggingContext>>
。然而,我不知道在多线程场景下实现类似行为的最佳方法是什么。
using(LoggingContext("Method 1"))
{
Task.WaitAll(
new Task(() => Method("Method A", "A"),
new Task(() => Method("Method B", "B")))
}
void Method(string contextName, string message)
{
using(new LoggingContext(contextName)
{
_logger.Log(message)
}
}
期望的日志应该是这样的:
Method 1 > Method A > A Method 1 > Method B > B
当然,一个任务可以在另一个任务中启动,情况会更加复杂。
还有一件事需要注意: 由于某些遗留原因,我无法在创建LoggingContext时传递所有依赖项,必须采用静态解决方案。
我能想到唯一的想法是在创建新任务时使用ExecutionContext.SupressFlow,并将当前堆栈复制到新的AsyncLocal对象中,但这是一个好的解决方案吗?修改执行上下文似乎对我来说有点不安全。