溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中如何實現異步調用

發(fā)布時間:2021-07-07 16:46:07 來源:億速云 閱讀:705 作者:Leah 欄目:編程語言

C#中如何實現異步調用,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

.NET Framework 允許您C#異步調用任何方法。定義與您需要調用的方法具有相同簽名的委托;公共語言運行庫將自動為該委托定義具有適當簽名的 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法用于啟動C#異步調用。它與您需要異步執(zhí)行的方法具有相同的參數,只不過還有兩個額外的參數(將在稍后描述)。BeginInvoke 立即返回,不等待C#異步調用完成。BeginInvoke 返回 IasyncResult,可用于監(jiān)視調用進度。

EndInvoke 方法用于檢索C#異步調用結果。調用 BeginInvoke 后可隨時調用 EndInvoke 方法;如果C#異步調用未完成,EndInvoke 將一直阻塞到C#異步調用完成。EndInvoke 的參數包括您需要異步執(zhí)行的方法的 out 和 ref 參數(在 Visual Basic 中為ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

注意   Visual Studio .NET 中的智能感知功能會顯示 BeginInvoke 和 EndInvoke 的參數。如果您沒有使用 Visual Studio 或類似的工具,或者您使用的是 C# 和 Visual Studio .NET,請參見異步方法簽名獲取有關運行庫為這些方法定義的參數的描述。

本主題中的代碼演示了四種使用 BeginInvoke 和 EndInvoke 進行C#異步調用的常用方法。調用了 BeginInvoke 后,可以:

· 進行某些操作,然后調用 EndInvoke 一直阻塞到調用完成。

· 使用 IAsyncResult.AsyncWaitHandle 獲取 WaitHandle,使用它的 WaitOne 方法將執(zhí)行一直阻塞到發(fā)出 WaitHandle 信號,然后調用 EndInvoke。

· 輪詢由 BeginInvoke 返回的 IAsyncResult,確定C#異步調用何時完成,然后調用 EndInvoke。

· 將用于回調方法的委托傳遞給 BeginInvoke。該方法在C#異步調用完成后在 ThreadPool 線程上執(zhí)行,它可以調用 EndInvoke。

警告:始終在C#異步調用完成后調用 EndInvoke。

測試方法和異步委托

四個示例全部使用同一個長期運行的測試方法 TestMethod。該方法顯示一個表明它已開始處理的控制臺信息,休眠幾秒鐘,然后結束。TestMethod 有一個 out 參數(在 Visual Basic 中為ByRef),它演示了如何將這些參數添加到 BeginInvoke 和 EndInvoke 的簽名中。您可以用類似的方式處理 ref 參數(在 Visual Basic 中為 ByRef)。

下面的代碼示例顯示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,請將示例代碼追加到這段代碼中。

注意   為了簡化這些示例,TestMethod 在獨立于 Main() 的類中聲明?;蛘?,TestMethod 可以是包含 Main() 的同一類中的 static 方法(在 Visual Basic 中為 Shared)。

using System;  using System.Threading;    public class AsyncDemo {  // The method to be executed asynchronously.  //  public string TestMethod(  int callDuration, out int threadId) {  Console.WriteLine("Test method begins.");  Thread.Sleep(callDuration);  threadId = AppDomain.GetCurrentThreadId();  return "MyCallTime was " + callDuration.ToString();  }  }   // The delegate must have the same signature as the method  // you want to call asynchronously.  public delegate string AsyncDelegate(  int callDuration, out int threadId);      using System;  using System.Threading;    public class AsyncDemo {  // The method to be executed asynchronously.  //  public string TestMethod(  int callDuration, out int threadId) {  Console.WriteLine("Test method begins.");  Thread.Sleep(callDuration);  threadId = AppDomain.GetCurrentThreadId();  return "MyCallTime was " + callDuration.ToString();  }  }   // The delegate must have the same signature as the method  // you want to call asynchronously.  public delegate string AsyncDelegate(  int callDuration, out int threadId);

C#異步調用四大方法之使用 EndInvoke 等待異步調用

異步執(zhí)行方法的最簡單方式是以 BeginInvoke 開始,對主線程執(zhí)行一些操作,然后調用 EndInvoke。EndInvoke 直到C#異步調用完成后才返回。這種技術非常適合文件或網絡操作,但是由于它阻塞 EndInvoke,所以不要從用戶界面的服務線程中使用它。

public class AsyncMain {  static void Main(string[] args) {  // The asynchronous method puts the thread id here.  int threadId;   // Create an instance of the test class.  AsyncDemo ad = new AsyncDemo();   // Create the delegate.  AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);       // Initiate the asychronous call.  IAsyncResult ar = dlgt.BeginInvoke(3000,   out threadId, null, null);   Thread.Sleep(0);  Console.WriteLine("Main thread {0} does some work.",  AppDomain.GetCurrentThreadId());   // Call EndInvoke to Wait for   //the asynchronous call to complete,  // and to retrieve the results.  string ret = dlgt.EndInvoke(out threadId, ar);   Console.WriteLine("The call executed on thread {0},   with return value \"{1}\".", threadId, ret);  }  }

C#異步調用四大方法之使用 WaitHandle 等待異步調用

等待 WaitHandle 是一項常用的線程同步技術。您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 屬性來獲取 WaitHandle。C#異步調用完成時會發(fā)出 WaitHandle 信號,而您可以通過調用它的 WaitOne 等待它。

如果您使用 WaitHandle,則在C#異步調用完成之后,但在通過調用 EndInvoke 檢索結果之前,可以執(zhí)行其他處理。

public class AsyncMain {  static void Main(string[] args) {  // The asynchronous method puts the thread id here.  int threadId;   // Create an instance of the test class.  AsyncDemo ad = new AsyncDemo();   // Create the delegate.  AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);       // Initiate the asychronous call.  IAsyncResult ar = dlgt.BeginInvoke(3000,   out threadId, null, null);   Thread.Sleep(0);  Console.WriteLine("Main thread {0} does some work.",  AppDomain.GetCurrentThreadId());   // Wait for the WaitHandle to become signaled.  ar.AsyncWaitHandle.WaitOne();   // Perform additional processing here.  // Call EndInvoke to retrieve the results.  string ret = dlgt.EndInvoke(out threadId, ar);   Console.WriteLine("The call executed on thread {0},   with return value \"{1}\".", threadId, ret);  }  }

C#異步調用四大方法之輪詢異步調用完成

您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 屬性來發(fā)現C#異步調用何時完成。從用戶界面的服務線程中進行C#異步調用時可以執(zhí)行此操作。輪詢完成允許用戶界面線程繼續(xù)處理用戶輸入。

public class AsyncMain {  static void Main(string[] args) {  // The asynchronous method puts the thread id here.  int threadId;   // Create an instance of the test class.  AsyncDemo ad = new AsyncDemo();   // Create the delegate.  AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);       // Initiate the asychronous call.  IAsyncResult ar = dlgt.BeginInvoke(3000,   out threadId, null, null);   // Poll while simulating work.  while(ar.IsCompleted == false) {  Thread.Sleep(10);  }   // Call EndInvoke to retrieve the results.  string ret = dlgt.EndInvoke(out threadId, ar);   Console.WriteLine("The call executed on thread {0},   with return value \"{1}\".", threadId, ret);  }  }

C#異步調用四大方法之異步調用完成時執(zhí)行回調方法

如果啟動異步調用的線程不需要處理調用結果,則可以在調用完成時執(zhí)行回調方法?;卣{方法在 ThreadPool 線程上執(zhí)行。

要使用回調方法,必須將代表該方法的 AsyncCallback 委托傳遞給 BeginInvoke。也可以傳遞包含回調方法將要使用的信息的對象。例如,可以傳遞啟動調用時曾使用的委托,以便回調方法能夠調用 EndInvoke。

public class AsyncMain {  // Asynchronous method puts the thread id here.  private static int threadId;   static void Main(string[] args) {  // Create an instance of the test class.  AsyncDemo ad = new AsyncDemo();   // Create the delegate.  AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);       // Initiate the asychronous call.  Include an AsyncCallback  // delegate representing the callback method, and the data  // needed to call EndInvoke.  IAsyncResult ar = dlgt.BeginInvoke(3000,  out threadId,   new AsyncCallback(CallbackMethod),  dlgt );   Console.WriteLine("Press Enter to close application.");  Console.ReadLine();  }   // Callback method must have the same signature as the  // AsyncCallback delegate.  static void CallbackMethod(IAsyncResult ar) {  // Retrieve the delegate.  AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState;   // Call EndInvoke to retrieve the results.  string ret = dlgt.EndInvoke(out threadId, ar);   Console.WriteLine("The call executed on thread {0},   with return value \"{1}\".", threadId, ret);  }  }

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI