Ric*_*ard 9 c# log4net asynchronous async-await
我一直在尝试使用Log4nets LogicalThreadContext为我的每个日志条目提供上下文.我的应用程序非常重视async/await,但是从阅读各种文章开始,LogicalThreadContext应该可以与.NET 4.5以后的异步代码一起正常工作.我正在使用.NET 4.5.1和log4net 2.0.3
我遇到了Stephen Cleary关于日志记录和.NET CallContext的一篇很棒的文章,结果我决定采用他的代码并使其适应log4net,试图看看我的代码中是否有错误可能有一直在引发这个问题.
首先,我完全按原样运行Stephens代码并得到预期的输出
Main 1: <SomeWork>
Main 1 A: <MoreWork>
Main 2: <SomeWork>
Main 2 A: <MoreWork>
Main 1 A: </MoreWork>
Main 1 B: <MoreWork>
Main 2 A: </MoreWork>
Main 2 B: <MoreWork>
Main 2 B: </MoreWork>
Main 2: </SomeWork>
Main 1 B: </MoreWork>
Main 1: </SomeWork>
Run Code Online (Sandbox Code Playgroud)
接下来,我修改了代码以使用log4net而不是Stephens自定义 MyStack
internal class Program
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
private const string StackName = "test";
private static void Main(string[] args)
{
XmlConfigurator.Configure();
using (LogicalThreadContext.Stacks[StackName].Push("Main"))
{
Task.WhenAll(SomeWork("1"), SomeWork("2")).Wait();
}
Console.ReadKey();
}
private static async Task SomeWork(string stackName)
{
using (LogicalThreadContext.Stacks[StackName].Push(stackName))
{
Log.Info("<SomeWork>");
await MoreWork("A");
await MoreWork("B");
Log.Info("</SomeWork>");
}
}
private static async Task MoreWork(string stackName)
{
using (LogicalThreadContext.Stacks[StackName].Push(stackName))
{
Log.Info("<MoreWork>");
await Task.Delay(10);
Log.Info("</MoreWork>");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望得到与以前类似的输出,但这次我得到了以下内容
Main 1: <SomeWork>
Main 1 A: <MoreWork>
Main 1 A 2: <SomeWork>
Main 1 A 2 A: <MoreWork>
Main 1 A 2 A: </MoreWork>
Main 1 B: <MoreWork>
Main 1 B: </MoreWork>
Main 1 B B: <MoreWork>
Main 1 B B: </MoreWork>
Main 1 B: </MoreWork>
Main 1: </SomeWork>
Main 1: </SomeWork>
Run Code Online (Sandbox Code Playgroud)
请注意,单独的逻辑线程上下文开始重叠.这向我表明log4net没有正确使用CallContext但是从我能找到的所有内容看起来他们已经解决了这个问题.
有没有其他人遇到这个或知道为什么会发生这种情况?
Ste*_*ary 10
不幸的是,看起来log4net 仍然无法与async逻辑堆栈一起使用.
log4net NuGet包2.0.3是log4net 1.2.13(截至今天的当前版本).报告了一个错误(LOG4NET-317)因为当时LogicalThreadContext使用CallContext而不是LogicalCallContext.
在当前版本LogicalThreadContext确实使用LogicalThreadContext,但目前的版本ThreadContextStacks并没有正确地使用一个不可变的堆栈.
有趣的是,Andrew Arnott在原始错误报告中正确地指出他们必须使用不可变堆栈.在2011年.
随意编写一个最小的repro并将其报告为log4net错误.关键方案是在使用组合的多个任务中使用堆栈Task.WhenAll.