如何使用Lazy <stackframe> </stackframe>创建可预测的输出

时间:2010-12-20 01:54:51

标签: c# .net logging system.diagnostics diagnostics

我正在研究一些内部日志记录框架,为了性能,懒得获得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,直到我用未知方法检测到第一帧。

我真的希望有更好的解决方案。

1 个答案:

答案 0 :(得分:0)

我不知道这要好得多,但是不是寻找一个未知的方法,寻找一个不同的源类可能更简单。这有点粗糙,但是这样的工作可以在进入日志记录类之前为您提供最后一帧而不必维护“已知”方法名称列表(假设日志记录方法不是静态的......)? / p>

public void DoStuff()
{
    int index = 0;
    StackFrame frame = new StackFrame(index++);
    while (this.GetType().Name.Equals(frame.GetMethod().DeclaringType.Name))
    {
        frame = new StackFrame(index++);
    }
    //...
}