【发布时间】:2018-02-28 12:39:36
【问题描述】:
在 .NETCore 中,我想支持这样的场景,我在某些上下文中包装代码,例如:
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 中,例如一些 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)
}
}
所需的日志如下所示:
方法 1 > 方法 A > A
方法一 > 方法 B > B
当然,一项任务可以从另一项任务开始,情况会变得更加复杂。
还有一点需要注意: 由于某些遗留原因,不可能在我创建 LoggingContext 的任何地方传递依赖关系,它必须是一些静态解决方案。
我能想到的唯一想法是在创建新任务并将当前堆栈复制到新的AsyncLocal 对象时使用ExecutionContext.SupressFlow,但这是一个好的解决方案吗?搞乱执行上下文对我来说似乎有点不安全。
【问题讨论】:
标签: c# multithreading asp.net-core task-parallel-library