如何在c#中打印程序的执行流程
How to print the flow of execution of a program in c#
我正在尝试了解如何打印程序的执行流程。
我写了一些简单的代码来证明我的困境。
我希望打印如下内容:
在classA,主要。
在classB中,方法B。
在 class C 中,方法 C.
StackTrace 似乎给了我很多难以阅读的信息。有没有更简单的方法,或者更容易阅读 StackTrace 的方法?实际代码要大得多,我不想在每个方法中都放置 print 语句,所以我想这样的事情可能会使调试更容易。另外,我不能在实际代码中使用 Visual Studio 的调试器。所以如果你们能告诉我使用哪个函数,如果不是 StackTrace,那会为我打印必要的信息,我将不胜感激。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackTrace
{
public class A
{
public static void Main(string[] args)
{
B newB = new B();
newB.methodB();
Console.WriteLine("StackTrace: {0}", Environment.StackTrace); //I'd like to get the entire execution flow printed here
Console.ReadKey(); //just for testing, don't worry about this.
}
}
public class B
{
public void methodB()
{
C newC = new C();
//Console.WriteLine("In class B, method B");
newC.methodC();
}
}
public class C
{
public void methodC()
{
//Console.WriteLine("In class C, method C");
}
}
}
所以对于每个回复我的原始线程的人来说,你可能对我到目前为止的想法感兴趣。也许你们或其他人可以添加到这个讨论中,我们可以找到一个更永久的解决方案。
但是,这是我最接近自动化的:
1) 创建此 function/method 并将其添加到每个 class:
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
2) 将此行粘贴到代码库的相关区域:
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
3) 另外请看我修改后的代码,注意我们需要添加这两个用例:
使用System.Diagnostics;
使用 System.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Reflection;
namespace StackTraceTest
{
public class A
{
public static void Main(string[] args)
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
B newB = new B();
newB.methodB();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
/*for (int i = 0; i < stackTrace.FrameCount;i++)
{
LogInfo(stackTrace.GetFrame(i).GetType().Name, stackTrace.GetFrame(i).GetMethod().Name);
}*/
Console.ReadLine();
}
public static void LogInfo(string className, string methodName)
{
string info = ("In class: " +className +" In method: " +methodName);
Console.WriteLine(info);
}
}
public class B
{
public void methodB()
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
C newC = new C();
newC.methodC();
}
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
}
public class C
{
public void methodC()
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
//Console.WriteLine("StackTrace: {0}", Environment.StackTrace);
}
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
}
}
4) 输出现在变为:
In class: A In method: Main
In class: B In method: methodB
In class: C In method: methodC
In class: A In method: Main
5) 我想向你们指出的几件事:我认为注释掉的 for 循环将是可以在一行中解决所有问题的灵丹妙药,但它给出了输出:
In class: StackFrame In method: Main
In class: StackFrame In method: _nExecuteAssembly
In class: StackFrame In method: ExecuteAssembly
In class: StackFrame In method: RunUsersAssembly
In class: StackFrame In method: ThreadStart_Context
In class: StackFrame In method: RunInternal
In class: StackFrame In method: Run
In class: StackFrame In method: Run
In class: StackFrame In method: ThreadStart
还要注意注释掉的行,在 class C:
如果您取消注释,它会正确地为您提供整个执行流程(不会 post 结果,因为它包含个人信息)。然而,这意味着我需要深入挖掘代码,找到最后调用的方法,并将这行代码添加到其中。
6) 来源:
How performant is StackFrame?
How can I find the method that called the current method?
C# getting its own class name
请告诉我你们的想法。谢谢。
使用 postsharp 的免费版本,你可以很容易地做到这一点。首先,创建一个可以标记到方法上的属性:
[PSerializable]
public class LogInvocationAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
// TODO: use your existing logging method here. simple example here for now.
Console.WriteLine($"{args.Instance.GetType()}.{args.Method.Name}");
// pass the call through to the original receiver
args.Proceed();
}
}
之后,任何你想记录的方法都可以像这样应用这个属性:
[LogInvocation]
public void SomeMethod(int someArg)
{
// do stuff
}
使用 postsharp 的付费版本,您实际上可以在基础 class 级别应用类似的东西,并让它也自动应用于儿童(SO 参考 here),但对于您想要的将属性应用于您的方法是获得所需内容的简单方法。
我正在尝试了解如何打印程序的执行流程。 我写了一些简单的代码来证明我的困境。
我希望打印如下内容: 在classA,主要。 在classB中,方法B。 在 class C 中,方法 C.
StackTrace 似乎给了我很多难以阅读的信息。有没有更简单的方法,或者更容易阅读 StackTrace 的方法?实际代码要大得多,我不想在每个方法中都放置 print 语句,所以我想这样的事情可能会使调试更容易。另外,我不能在实际代码中使用 Visual Studio 的调试器。所以如果你们能告诉我使用哪个函数,如果不是 StackTrace,那会为我打印必要的信息,我将不胜感激。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackTrace
{
public class A
{
public static void Main(string[] args)
{
B newB = new B();
newB.methodB();
Console.WriteLine("StackTrace: {0}", Environment.StackTrace); //I'd like to get the entire execution flow printed here
Console.ReadKey(); //just for testing, don't worry about this.
}
}
public class B
{
public void methodB()
{
C newC = new C();
//Console.WriteLine("In class B, method B");
newC.methodC();
}
}
public class C
{
public void methodC()
{
//Console.WriteLine("In class C, method C");
}
}
}
所以对于每个回复我的原始线程的人来说,你可能对我到目前为止的想法感兴趣。也许你们或其他人可以添加到这个讨论中,我们可以找到一个更永久的解决方案。 但是,这是我最接近自动化的:
1) 创建此 function/method 并将其添加到每个 class:
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
2) 将此行粘贴到代码库的相关区域:
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
3) 另外请看我修改后的代码,注意我们需要添加这两个用例:
使用System.Diagnostics;
使用 System.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Reflection;
namespace StackTraceTest
{
public class A
{
public static void Main(string[] args)
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
B newB = new B();
newB.methodB();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
/*for (int i = 0; i < stackTrace.FrameCount;i++)
{
LogInfo(stackTrace.GetFrame(i).GetType().Name, stackTrace.GetFrame(i).GetMethod().Name);
}*/
Console.ReadLine();
}
public static void LogInfo(string className, string methodName)
{
string info = ("In class: " +className +" In method: " +methodName);
Console.WriteLine(info);
}
}
public class B
{
public void methodB()
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
C newC = new C();
newC.methodC();
}
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
}
public class C
{
public void methodC()
{
StackTrace stackTrace = new StackTrace();
LogInfo(MethodBase.GetCurrentMethod().DeclaringType.Name, stackTrace.GetFrame(0).GetMethod().Name);
//Console.WriteLine("StackTrace: {0}", Environment.StackTrace);
}
public void LogInfo(string className, string methodName)
{
string info = ("In class: " + className + " In method: " + methodName);
Console.WriteLine(info);
}
}
}
4) 输出现在变为:
In class: A In method: Main
In class: B In method: methodB
In class: C In method: methodC
In class: A In method: Main
5) 我想向你们指出的几件事:我认为注释掉的 for 循环将是可以在一行中解决所有问题的灵丹妙药,但它给出了输出:
In class: StackFrame In method: Main
In class: StackFrame In method: _nExecuteAssembly
In class: StackFrame In method: ExecuteAssembly
In class: StackFrame In method: RunUsersAssembly
In class: StackFrame In method: ThreadStart_Context
In class: StackFrame In method: RunInternal
In class: StackFrame In method: Run
In class: StackFrame In method: Run
In class: StackFrame In method: ThreadStart
还要注意注释掉的行,在 class C: 如果您取消注释,它会正确地为您提供整个执行流程(不会 post 结果,因为它包含个人信息)。然而,这意味着我需要深入挖掘代码,找到最后调用的方法,并将这行代码添加到其中。
6) 来源: How performant is StackFrame?
How can I find the method that called the current method?
C# getting its own class name
请告诉我你们的想法。谢谢。
使用 postsharp 的免费版本,你可以很容易地做到这一点。首先,创建一个可以标记到方法上的属性:
[PSerializable]
public class LogInvocationAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
// TODO: use your existing logging method here. simple example here for now.
Console.WriteLine($"{args.Instance.GetType()}.{args.Method.Name}");
// pass the call through to the original receiver
args.Proceed();
}
}
之后,任何你想记录的方法都可以像这样应用这个属性:
[LogInvocation]
public void SomeMethod(int someArg)
{
// do stuff
}
使用 postsharp 的付费版本,您实际上可以在基础 class 级别应用类似的东西,并让它也自动应用于儿童(SO 参考 here),但对于您想要的将属性应用于您的方法是获得所需内容的简单方法。