C#實現(xiàn)異步的常用方式總結(jié)

c#實現(xiàn)異步的常用方式總結(jié)

 

前言

微信群里的一個提問引發(fā)的這個問題,c#異步有多少種實現(xiàn)方式?首先想要知道c#異步有多少中實現(xiàn)方式,首先我們要知道.net提供的執(zhí)行異步操作的三種模式,然后再去了解c#異步實現(xiàn)的方式。

 

.net異步編程模式

.net 提供了執(zhí)行異步操作的三種模式:

  • 基于任務(wù)的異步模式 (tap),該模式使用單一方法表示異步操作的開始和完成。 tap 是在 .net framework 4 中引入的。這是在 .net 中進(jìn)行異步編程的推薦方法。c# 中的async和await關(guān)鍵詞以及 visual basic 中的async和await運算符為 tap 添加了語言支持。 有關(guān)詳細(xì)信息,請參閱基于任務(wù)的異步模式 (tap)。
  • 基于事件的異步模式 (eap),是提供異步行為的基于事件的舊模型。 這種模式需要后綴為async的方法,以及一個或多個事件、事件處理程序委托類型和eventarg派生類型。 eap 是在 .net framework 2.0 中引入的。 建議新開發(fā)中不再使用這種模式。 有關(guān)詳細(xì)信息,請參閱基于事件的異步模式 (eap)。
  • 異步編程模型 (apm) 模式(也稱為iasyncresult模式),這是使用iasyncresult接口提供異步行為的舊模型。 在這種模式下,同步操作需要begin和end方法(例如,beginwrite和endwrite以實現(xiàn)異步寫入操作)。 不建議新的開發(fā)使用此模式。 有關(guān)詳細(xì)信息,請參閱異步編程模型 (apm)。

 

c#異步有四種實現(xiàn)方式

c# 異步有多種實現(xiàn)方式,可歸納為以下幾類:

1、異步方法(async methodtap模式)

使用async/await關(guān)鍵字實現(xiàn)異步編程,這是比較常用的一種異步實現(xiàn)方式。例如:

public async task testdosomeasync()
  {
      await task.delay(1000);
      console.writeline("async method completed.");
  }

2、任務(wù)并行庫(tpl, task parallel librarytap模式)

通過 task 和 task<t> 類型實現(xiàn)異步編程,可以利用多核處理器,并發(fā)執(zhí)行多個獨立的任務(wù)。例如:

public static async void main(string[] args)
  {
      await task.run(() =>
      {
          console.writeline("test task 1 completed.");
      });
      await task.run(() =>
      {
          console.writeline("test task 2 completed.");
      });
      // 等待所有任務(wù)完成
      task.waitall();
  }

3、asynchronous programming model(apm模式)

是一種經(jīng)典的異步編程模式,需要手動創(chuàng)建回調(diào)函數(shù),用于處理完成或錯誤的通知??梢酝ㄟ^ iasyncresult 設(shè)計模式的 begin 和 end 方法來實現(xiàn),其中 begin 方法開始異步操作,而 end 方法在異步操作完成時執(zhí)行,并返回異步操作的結(jié)果。

需要注意的是,apm 模式通過 iasyncresult 接口來存儲異步操作的狀態(tài)和結(jié)果,相對比較復(fù)雜,代碼量也較大。同時,在使用 apm 模式時,還需要手動處理回調(diào)函數(shù)和等待異步操作完成等細(xì)節(jié)工作,使得開發(fā)起來相對較為繁瑣。

class program
  {
      static void main(string[] args)
      {
          // 創(chuàng)建異步操作類實例
          myasyncclass asyncclass = new myasyncclass();

          // 開始異步操作
          iasyncresult result = asyncclass.begindowork(null, null);

          // 主線程執(zhí)行其他操作
          // 等待異步操作完成并獲取結(jié)果
          int res = asyncclass.enddowork(result);

          // 處理異步操作的結(jié)果
          console.writeline("result: " + res);

          console.readline();
      }
  }

  class myasyncclass
  {
      /// <summary>
      /// 異步執(zhí)行的方法
      /// </summary>
      /// <param name="callback">callback</param>
      /// <param name="state">state</param>
      /// <returns></returns>
      public iasyncresult begindowork(asynccallback callback, object state)
      {
          // 創(chuàng)建一個新的異步操作對象
          myasyncresult result = new myasyncresult(state);

          // 開始異步操作
          thread thread = new thread(() =>
          {
              try
              {
                  // 執(zhí)行一些操作
                  int res = 1 + 2;

                  // 設(shè)置異步操作的結(jié)果
                  result.result = res;

                  // 觸發(fā)回調(diào)函數(shù)
                  callback?.invoke(result);
              }
              catch (exception ex)
              {
                  // 設(shè)置異步操作的異常
                  result.error = ex;

                  // 觸發(fā)回調(diào)函數(shù)
                  callback?.invoke(result);
              }

          });
          thread.start();

          // 返回異步操作對象
          return result;
      }

      /// <summary>
      /// 結(jié)束異步執(zhí)行的方法
      /// </summary>
      /// <param name="result">result</param>
      /// <returns></returns>
      public int enddowork(iasyncresult result)
      {
          // 將 iasyncresult 轉(zhuǎn)換為 myasyncresult 類型,并等待異步操作完成
          myasyncresult myresult = (myasyncresult)result;
          myresult.asyncwaithandle.waitone();

          // 在異步操作中拋出異常
          if (myresult.error != null)
          {
              throw myresult.error;
          }

          // 返回異步操作的結(jié)果
          return myresult.result;
      }
  }

  class myasyncresult : iasyncresult
  {
      public bool iscompleted => asyncwaithandle.waitone(0);
      public waithandle asyncwaithandle { get; } = new manualresetevent(false);
      public object asyncstate { get; }
      public bool completedsynchronously => false;

      public int result { get; set; }

      /// <summary>
      /// 存儲異步操作的結(jié)果或異常信息
      /// </summary>
      public exception error { get; set; }

      /// <summary>
      /// 構(gòu)造函數(shù)
      /// </summary>
      /// <param name="asyncstate">asyncstate</param>
      public myasyncresult(object asyncstate)
      {
          asyncstate = asyncstate;
      }
  }

4、event-based asynchronous pattern(eap模式)

一種已過時的異步編程模式,需要使用事件來實現(xiàn)異步編程。例如:

需要注意的是,eap 模式通過事件來實現(xiàn)異步編程,相對于 apm 模式更加簡潔易懂,同時也避免了手動處理回調(diào)函數(shù)等細(xì)節(jié)工作。但是,eap 模式并不支持 async/await 異步關(guān)鍵字,因此在一些特定的場景下可能不夠靈活。

public class myasyncclass : component
  {
      /// <summary>
      /// 聲明一個委托類型,用于定義異步操作的方法簽名
      /// </summary>
      /// <param name="arg"></param>
      /// <returns></returns>
      public delegate int myasyncdelegate(int arg);

      /// <summary>
      /// 聲明一個事件,用于通知異步操作的完成
      /// </summary>
      public event myasyncdelegate operationnamecompleted;

      /// <summary>
      /// 異步執(zhí)行方法,接受一個參數(shù) arg
      /// </summary>
      /// <param name="arg"></param>
      public void doworkasync(int arg)
      {
          // 將異步操作放入線程池中執(zhí)行
          threadpool.queueuserworkitem(new waitcallback(dowork), arg);
      }

      /// <summary>
      /// 真正的異步操作
      /// </summary>
      /// <param name="obj"></param>
      private void dowork(object obj)
      {
          int arg = (int)obj;
          int res = arg + 1;

          // 觸發(fā)事件,傳遞異步操作的結(jié)果
          operationnamecompleted?.invoke(res);
      }
  }

以上就是c#實現(xiàn)異步的常用方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于c#異步的資料請關(guān)注碩編程其它相關(guān)文章!

下一節(jié):c#synchronizationcontext以及send和post使用解讀

c# 教程

相關(guān)文章
亚洲国产精品第一区二区,久久免费视频77,99V久久综合狠狠综合久久,国产免费久久九九免费视频