3

我正在开发一些内部日志框架,为了提高性能,懒惰地获取一个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,直到我用未知方法检测到第一帧。

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

4

1 回答 1

0

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

public void DoStuff()
{
    int index = 0;
    StackFrame frame = new StackFrame(index++);
    while (this.GetType().Name.Equals(frame.GetMethod().DeclaringType.Name))
    {
        frame = new StackFrame(index++);
    }
    //...
}
于 2010-12-22T15:12:58.813 回答