2

I want to get the name of this method by using Reflection etc...I use a lot of stuff but I 'm tired please help me. If the function is sync then it below code will work fine. Please go through the below code, that will clear you my question.

// this will work fine
public void Test()
{
// This GetCurrentMethod() will you the name of current method
string CurrentMethodName = GetCurrentMethod();
// output will be CurrentMethodName = Test
}


// this will not work
      public async Task<int> GETNumber(long ID)
      {
// This GetCurrentMethod() will you the name of current method if the method is sync or not async
string CurrentMethodName = GetCurrentMethod();
           return await Task.Run(() => { return 20; });
      }

This method provide me Name of non async method. but how I get above method name

>     [MethodImpl(MethodImplOptions.NoInlining)]
>           public static string GetCurrentMethod()
>           {
>                 var stackTrace = new StackTrace();
>                 StackFrame stackFrame = stackTrace.GetFrame(1);
>                 return stackFrame.GetMethod().Name;
>           }

But this method is working only for not async method. So how get current async method name in c#

SunilPaul
  • 94
  • 1
  • 8
  • The problem here is that the "stack" in your specific case, using `Task.Run` isn't a natural stack as such, a threadpool thread has been spun up to run your anonymous method, as such, the stack doesn't contain anything specific to the `GETNumber` method. *However*, in this particular case, the generated name for your anonymous method contains the name, the name of the method will be something like `.b__1_0`. – Lasse V. Karlsen Feb 09 '17 at 13:13
  • Now, the question is, what exactly do you need the name for? – Lasse V. Karlsen Feb 09 '17 at 13:13
  • Check: [Get current method name from async function](http://stackoverflow.com/q/20158902/1351076) – krlzlx Feb 09 '17 at 13:13
  • The duplicate is only valid for your specific case, however, which involves an anonymous method or a lambda expression. If your async method is a normal method, this won't work. Are you sure `nameof(GETNumber)` isn't going to do the trick? – Lasse V. Karlsen Feb 09 '17 at 13:15

1 Answers1

5

What you want is not really possible. The compiler creates a state machine for the async method, something like that

public class GetNumberStateMachine : IAsyncStateMachine
{
    // ....
    void IAsyncStateMachine.MoveNext()
    {
        // here your actual code happens in steps between the 
        // await calls
    }
}

And converts your method into something like that:

public async Task<int> GetNumber()
{
     GetNumberStateMachin stateMachine = new GetNumberStatemachine();
     stateMachine.\u003C\u003Et__builder = AsyncTaskMethodBuilder<int>.Create();
     stateMachine.\u003C\u003E1__state = -1;
     stateMachine.\u003C\u003Et__builder.Start<GetNumberStatemachine>(ref stateMachine);
     return stateMachine.\u003C\u003Et__builder.Task;
}

So what calls your GetCurrentMethod() at runtime is no longer your GetNumber().


But you can get the name of the calling method via the CallerMemberNameAttribute:

public static string GetCurrentMethod([CallingMemberName] string method = "")
{
     return method;
}

public async Task<int> GetNumber(long ID)
{
   int result = await Task.Run(() => { return 20; });
   Console.WriteLine(GetCurrentMethod()); // prints GetNumber
   return result;
}

This even works with async methods (I'm not sure, but I guess the argument is replaced at compile time).

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • Side note - same is true for iterator methods which are yielding results. Though is it possible to still get name of method which contains state machine? – Sergey Berezovskiy Feb 09 '17 at 13:19