最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c# 在Emit代碼中如何await一個異步方法

 更新時間:2021年03月23日 11:10:34   作者:victor.x.qu  
這篇文章主要介紹了c# 在Emit代碼中如何await一個異步方法,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下

0. 前言

首先立馬解釋一波為啥會有這樣一篇偽標題的Demo隨筆呢?
不是本人有知識誤區(qū),或者要誤人子弟
因為大家都知道emit寫出來的都是同步方法,不可能await,至少現(xiàn)在這么多年來沒有提供對應的功能
這是之前某天在微信群看見討論怎么emit一個異步方法并包裝異步結(jié)構(gòu),簡單幾句文字也未能清晰的表達
所以趁著元旦節(jié)放假有點時間,
簡單列舉三種我知道方式去達到這樣的效果
三種方法都是繞過emit直接書寫emit代碼,而是將對應邏輯轉(zhuǎn)到其他方法中,最后emit調(diào)用方法達到效果

Demo 說明

原始方法是個延遲2秒之后返回55的方法:

  public static async Task<int> GetV()
  {
   await Task.Delay(2000);
   return 55;
  }

現(xiàn)在我們需要把 55 的結(jié)果加 6 ,讓最終的結(jié)果變?yōu)?61

我們的測試方法是這樣,會輸出一些簡單的時間,幫助我們了解執(zhí)行順序和異步情況

  private static async Task Test(MethodInfo method, MethodInfo awaitMehtod)
  {
   var caller = CreateCaller(method, awaitMehtod);
   Console.WriteLine($"Start {awaitMehtod.Name} at: {DateTime.Now}.");
   var task = caller();
   Console.WriteLine($"Call done at: {DateTime.Now}.");
   var number = await task;
   Console.WriteLine($"Hello {number} at: {DateTime.Now}.");
   Console.WriteLine($"End at: {DateTime.Now}.");
   Console.WriteLine();
  }

1. ContinueWith

  public static Func<Task<int>> CreateCaller(MethodInfo method, MethodInfo awaitMehtod)
  {
   var m = new DynamicMethod(Guid.NewGuid().ToString("N"), typeof(Task<int>), Type.EmptyTypes);
   var il = m.GetILGenerator();
   il.Emit(OpCodes.Call, method);
   il.Emit(OpCodes.Call, typeof(Program).GetMethod(nameof(Program.AddSixUseContinueWith))); // 這里是差異點
   il.Emit(OpCodes.Ret);

   return m.CreateDelegate(typeof(Func<Task<int>>)) as Func<Task<int>>;
  }

  public static Task<int> AddSixUseContinueWith(Task<int> task)
  {
   return task.ContinueWith(i =>
   {
    Console.WriteLine($"AddSixUseContinueWith is: {DateTime.Now}.");
    return i.Result + 6;
   });
  }

測試結(jié)果:

Start AddSixUseContinueWith at: 2021/1/2 13:34:55.
Call done at: 2021/1/2 13:34:55.
AddSixUseContinueWith is: 2021/1/2 13:34:57.
Hello 61 at: 2021/1/2 13:34:57.
End at: 2021/1/2 13:34:57.

優(yōu)點
還是真正的異步

缺點
成本比較大,畢竟這樣沒有了狀態(tài)機等等優(yōu)化,(成本在 ns 級別哦,不是大家想的 ms哦)

2. GetAwaiter().GetResult()

  public static Func<Task<int>> CreateCaller(MethodInfo method, MethodInfo awaitMehtod)
  {
   var m = new DynamicMethod(Guid.NewGuid().ToString("N"), typeof(Task<int>), Type.EmptyTypes);
   var il = m.GetILGenerator();
   il.Emit(OpCodes.Call, method);
   il.Emit(OpCodes.Call, typeof(Program).GetMethod(nameof(Program.AddSixUseAwaiter))); // 這里是差異點
   il.Emit(OpCodes.Ret);

   return m.CreateDelegate(typeof(Func<Task<int>>)) as Func<Task<int>>;
  }

  public static Task<int> AddSixUseAwaiter(Task<int> task)
  {
   var r = task.ConfigureAwait(false).GetAwaiter().GetResult() + 6;
   Console.WriteLine($"AddSixUseAwaiter is: {DateTime.Now}.");
   return Task.FromResult(r);
  }

測試結(jié)果:

Start AddSixUseAwaiter at: 2021/1/2 13:34:57.
AddSixUseAwaiter is: 2021/1/2 13:34:59.
Call done at: 2021/1/2 13:34:59.
Hello 61 at: 2021/1/2 13:34:59.
End at: 2021/1/2 13:34:59.

優(yōu)點
執(zhí)行時間上消耗很小

缺點
當然這樣 異步都變成了同步,所以可能會在某些情況下我們操作不當?shù)拇a從而導致失去異步方法的優(yōu)勢

3. async/await

  public static Func<Task<int>> CreateCaller(MethodInfo method, MethodInfo awaitMehtod)
  {
   var m = new DynamicMethod(Guid.NewGuid().ToString("N"), typeof(Task<int>), Type.EmptyTypes);
   var il = m.GetILGenerator();
   il.Emit(OpCodes.Call, method);
   il.Emit(OpCodes.Call, typeof(Program).GetMethod(nameof(Program.AddSixUseAsyncAwait))); // 這里是差異點
   il.Emit(OpCodes.Ret);

   return m.CreateDelegate(typeof(Func<Task<int>>)) as Func<Task<int>>;
  }

  public static async Task<int> AddSixUseAsyncAwait(Task<int> task)
  {
   var r = await task;
   Console.WriteLine($"AddSixUseAsyncAwait is: {DateTime.Now}.");
   return r + 6;
  }

測試結(jié)果:

Start AddSixUseAsyncAwait at: 2021/1/2 13:34:59.
Call done at: 2021/1/2 13:34:59.
AddSixUseAsyncAwait is: 2021/1/2 13:35:01.
Hello 61 at: 2021/1/2 13:35:01.
End at: 2021/1/2 13:35:01.

優(yōu)點
async / await 本身的優(yōu)勢都沒有損失

缺點
原本想在 emit 中 對result的處理邏輯 必須遷移到 async / await 方法中,emit代碼必須好好設計

完整Demo放在

https://github.com/fs7744/grocery/blob/main/csharp/emit_await/EmitAwaitDemo/Program.cs

分享不易,如果能給予一點動力,不勝感激:關注一下本人的開源項目: Norns.Urd

以上就是c# 在Emit代碼中如何await一個異步方法的詳細內(nèi)容,更多關于c# Emit代碼await一個異步方法的資料請關注腳本之家其它相關文章!

相關文章

  • C#的并發(fā)機制優(yōu)秀在哪你知道么

    C#的并發(fā)機制優(yōu)秀在哪你知道么

    這篇文章主要為大家詳細介紹了C#的并發(fā)機制,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C# list<T>去重的實現(xiàn)

    C# list<T>去重的實現(xiàn)

    List集合在開發(fā)過程中很常見,經(jīng)常我們要對該集合進行一系列操作,本文主要介紹了C# list<T>去重的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • C#?HttpClient超時重試機制詳解

    C#?HttpClient超時重試機制詳解

    超時重試的實現(xiàn)方式可以使用循環(huán)結(jié)構(gòu),在請求發(fā)起后等待一定時間,若超時未收到響應,則再次發(fā)起請求,循環(huán)次數(shù)可以根據(jù)實際情況進行設置,一般建議不超過三次,這篇文章主要介紹了C#?HttpClient超時重試,需要的朋友可以參考下
    2023-06-06
  • C#實現(xiàn)Quartz任務調(diào)度的示例代碼

    C#實現(xiàn)Quartz任務調(diào)度的示例代碼

    使用 Quartz.NET,你可以很容易地安排任務在應用程序啟動時運行,或者每天、每周、每月的特定時間運行,甚至可以基于更復雜的調(diào)度規(guī)則,本文給大家介紹了C#實現(xiàn)Quartz任務調(diào)度,需要的朋友可以參考下
    2024-04-04
  • C#實現(xiàn)Winform中打開網(wǎng)頁頁面的方法

    C#實現(xiàn)Winform中打開網(wǎng)頁頁面的方法

    這篇文章主要介紹了C#實現(xiàn)Winform中打開網(wǎng)頁頁面的方法,涉及WinForm中WebBrowser的相關使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#線程倒計時器源碼分享

    C#線程倒計時器源碼分享

    這篇文章主要為大家分享了C#線程倒計時器源碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C#中實現(xiàn)線程安全單例模式的多種方法

    C#中實現(xiàn)線程安全單例模式的多種方法

    在C#中實現(xiàn)線程安全的單例模式通常涉及確保類的實例在多線程環(huán)境中只被創(chuàng)建一次,并且這個實例在應用程序的生命周期內(nèi)是唯一的,以下是幾種常見的方法來實現(xiàn)線程安全的單例模式,需要的朋友可以參考下
    2025-01-01
  • 詳解C# parallel中并行計算的四種寫法總結(jié)

    詳解C# parallel中并行計算的四種寫法總結(jié)

    在C#中,parallel關鍵字可以用于并行計算。本文為大家總結(jié)了四種C# parallel并行計算的方法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-11-11
  • C#使用jQuery實現(xiàn)無刷新評論提交的方法

    C#使用jQuery實現(xiàn)無刷新評論提交的方法

    這篇文章主要介紹了C#使用jQuery實現(xiàn)無刷新評論提交的方法,涉及C#結(jié)合jQuery進行Ajax操作的相關技巧,非常具有實用價值,需要的朋友可以參考下
    2015-05-05
  • C# 輸出字符串到文本文件中的實現(xiàn)代碼

    C# 輸出字符串到文本文件中的實現(xiàn)代碼

    本文通過一個簡單的代碼給大家介紹C# 輸出字符串到文本文件中,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-05-05

最新評論

江都市| 南乐县| 柯坪县| 都江堰市| 永安市| 石门县| 梅州市| 胶州市| 邓州市| 六安市| 杭州市| 泌阳县| 同江市| 邯郸市| 合水县| 新余市| 行唐县| 旬阳县| 郸城县| 互助| 延川县| 旌德县| 镇雄县| 阿荣旗| 顺平县| 普陀区| 仙桃市| 景泰县| 玉林市| 布拖县| 江安县| 嘉黎县| 阳城县| 逊克县| 工布江达县| 呼和浩特市| 渝北区| 万年县| 洪江市| 深泽县| 奎屯市|