如何使用 Lazy创建可预测的输出
我正在开发一些内部日志框架,为了性能的考虑,惰性地获取一个 StackFrame 似乎是个好主意。我想使用这个 StackFrame 来获取日志框架之外的第一个方法。
我最初的想法是这样的:
using System;
using System.Diagnostics;
using NUnit.Framework;
[TestFixture]
public class Test
{
[Test]
public void Caller()
{
NeedsToNowCaller();
}
public void NeedsToNowCaller()
{
Processor.GetName(() => new StackFrame(4));
Really();
Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);
}
public void Really()
{
Assert.AreEqual("Caller",Processor.stackFrame.Value.GetMethod().Name);
}
}
public static class Processor
{
public static Lazy<StackFrame> stackFrame;
public static void GetName(Func<StackFrame> stackFrameProvider)
{
stackFrame = new Lazy<StackFrame>(stackFrameProvider);
}
}
但是当你交换这些行时:
Really();
Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);
结果是不可预测的,因为调用堆栈发生了变化。无论如何,是否可以通过闭包获得本地作用域/框架的钩子,同时保留惰性。
我能想到的唯一解决方案是逐步执行 StackTrace,直到我使用未知方法检测到第一帧。
我真的希望有更好的解决方案。
I'm working on some internal logging framework and for the sake of performance it seems a good idea to lazily get a StackFrame
. I want to use this StackFrame
to get the first method outside my logging framework.
My initial idea was this:
using System;
using System.Diagnostics;
using NUnit.Framework;
[TestFixture]
public class Test
{
[Test]
public void Caller()
{
NeedsToNowCaller();
}
public void NeedsToNowCaller()
{
Processor.GetName(() => new StackFrame(4));
Really();
Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);
}
public void Really()
{
Assert.AreEqual("Caller",Processor.stackFrame.Value.GetMethod().Name);
}
}
public static class Processor
{
public static Lazy<StackFrame> stackFrame;
public static void GetName(Func<StackFrame> stackFrameProvider)
{
stackFrame = new Lazy<StackFrame>(stackFrameProvider);
}
}
But when you swap these lines:
Really();
Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);
Results are unpredictable, since the call stack is changed. Is there anyway to get a hook to the local scope/frame through a closure, while retaining the laziness.
The only solution i can think of is stepping through the StackTrace, until i detect the first frame with a unknown method.
I really hope there's a better solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道这是否好得多,但与其寻找未知的方法,不如寻找不同的源类可能更简单。这有点粗糙,但是像这样的东西会在进入日志记录类之前为您提供最后一帧,而不必维护“已知”方法名称列表(假设日志记录方法不是静态的......)?
I don't know that this is much better, but instead of looking for an unknown method, it might be simpler to look for a different source class. This is a bit rough, but would something like this work to give you the last frame before entering the logging class without having to maintain a list of "known" method names (assuming the logging method is not a static...)?