[英]C# Faster Stack Trace
我需要能够获得所有已调用的方法的清单。 不幸的是,我无法使用CallerInformation属性,以致于我几乎无法使用StackTrace。
我知道StackTrace的性能不是很好,所以我希望有其他替代方法可以做到这一点,而不会造成太大的性能。 我找到了这篇文章( https://ayende.com/blog/3879/reducing-the-cost-of-getting-a-stack-trace ),其中包含有关如何加快堆栈跟踪速度的示例,但我没有确定如何真正使用该名称。 这是我到目前为止的内容:
void Main()
{
var result = getTheStackTrace.Invoke();
}
private Func<object> getTheStackTrace;
public void FastStack()
{
var stackFrameHelperType = typeof(object).Assembly.GetType("System.Diagnostics.StackFrameHelper");
var GetStackFramesInternal = Type.GetType("System.Diagnostics.StackTrace, mscorlib").GetMethod("GetStackFramesInternal", BindingFlags.Static | BindingFlags.NonPublic);
var method = new DynamicMethod("GetStackTraceFast", typeof(object), new Type[0], typeof(StackTrace), true);
var generator = method.GetILGenerator();
generator.DeclareLocal(stackFrameHelperType);
generator.Emit(OpCodes.Ldc_I4_0);
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Newobj, stackFrameHelperType.GetConstructor(new[] { typeof(bool), typeof(Thread) }));
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldc_I4_0);
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Call, GetStackFramesInternal);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ret);
getTheStackTrace = (Func<object>)method.CreateDelegate(typeof(Func<object>));
}
我如何从对getTheStackTrace.Invoke()
的调用中getTheStackTrace.Invoke()
方法的名称,我对如何获取信息有些困惑。 任何帮助,将不胜感激。 谢谢。
如该示例所示,我实际上围绕StackFrameHelper类构建了类似的东西。 除了我使用缓存的/编译的表达式树来调用函数而不是IL之外,因为您需要调用大约5或6个方法,并且所有内容都是内部/私有的。 由于版权原因,我们无法发布课程,但至少可以为您指明正确的方向。 您需要先创建一个StackFrameHelper实例,然后调用GetStackFramesInternal,GetNumberOfFrames,然后为每个帧调用GetMethodBase,如果需要该信息,则可以调用GetFileName和GetLineNumber。
所有这些方法都在StackFrameHelper类上,除了在StackFrame类上的GetStackFramesInternal之外。
您上面的代码仅进入GetStackFramesInternal级别,该级别填充了StackFrameHelper实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.