1. 程式人生 > 其它 >C# 通過反射獲取async方法返回值

C# 通過反射獲取async方法返回值

首先,先看看非非同步方法如何獲得。

class Program
{
    static void Main(string[] args)
    {
        MethodInfo methodInfo = typeof(Program).GetMethod("SayHello");

        object result = methodInfo.Invoke(new Program(), new object[] { "張三" });

        Console.ReadKey();
    }

    public string SayHello(string name)
    {
        Console.WriteLine($"我叫{name}");
        return "OK";
    }
}

看起來非常簡單,因為Invoke的返回值就是Object,到時候只需要強轉一下即可。

那,如果是非同步方法呢?

class Program
{
    static void Main(string[] args)
    {
        MethodInfo methodInfo = typeof(Program).GetMethod("SayHello");

        object result = methodInfo.Invoke(new Program(), new object[] { "張三" });
       
        Console.ReadKey();
    }

    public async Task<string> SayHello(string name)
    {
        return await Task.Run(() =>
          {
              Console.WriteLine($"我叫{name}");
              return "OK";
          });

    }
}

可以看到返回值,但不是我們想要的結果。

於是想到,大概可能是要等待結果返回。於是呼叫Wait。

 static void Main(string[] args)
 {
     MethodInfo methodInfo = typeof(Program).GetMethod("SayHello");

     Task result =(Task) methodInfo.Invoke(new Program(), new object[] { "張三" });

     result.Wait();
     Console.ReadKey();
 }

但是又有一個問題,結果還是拿不到啊,因為Task 沒有Result的屬性,且GetAwaiter().GetResult()返回值也是void。
總不能每個方法都強轉成對應的Tsak泛型吧,像這樣??那泛型型別有int,string ,double。。。簡直要人老命。

 static void Main(string[] args)
 {
     MethodInfo methodInfo = typeof(Program).GetMethod("SayHello");

     Task<string> result = (Task<string>)methodInfo.Invoke(new Program(), new object[] { "張三" });

     result.Wait();
     string mes = result.Result;
     Console.ReadKey();
 }

 public async Task<string> SayHello(string name)
 {
     return await Task.Run(() =>
       {
           Console.WriteLine($"我叫{name}");
           return "OK";
       });

 }

莫愁前路無知己,天下誰人不會敲。立馬就想到了動態型別。當然了,Result就可以是Object了嘛。

static void Main(string[] args)
{
    MethodInfo methodInfo = typeof(Program).GetMethod("SayHello");

    dynamic result = methodInfo.Invoke(new Program(), new object[] { "張三" });

    result.Wait();
    string mes = result.Result;
    Console.ReadKey();
}

public async Task<string> SayHello(string name)
{
    return await Task.Run(() =>
      {
          Console.WriteLine($"我叫{name}");
          return "OK";
      });

}