Search code examples
c#embeddedexecution

How to print the flow of execution of a program in c#


I am trying to understand how I can print the execution flow of a program. I've wrote some simple code to demonstrate my dilemma.

I'd like for this to print something like: In class A, Main. In class B, methodB. In class C, methodC.

StackTrace seems to be giving me a lot of hard to read information. Is there a simpler method, or a way to have an easier to read StackTrace? The actual code is much larger and I don't want to put print statements in every single method, so I figured something like this may make debugging easier. Also, I can't use Visual Studio's debugger in the actual code. So if you guys could please advise me on which function to use, if not StackTrace, that would print the necessary information for me, I would appreciate it.

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");
            }
        }
}

Solution

  • Using the free version of postsharp you can do this very easily. First, create an attribute you can tag on to your methods:

    [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();
        }
    }
    

    After that, any method you want logged you can just apply this attribute to like this:

    [LogInvocation]
    public void SomeMethod(int someArg)
    {
        // do stuff
    }
    

    With paid versions of postsharp you can actually apply things like this at a base class level and have it automatically apply to children as well (SO reference here) but for what you want to do applying an attribute to your methods is a simple way to get what you want.