C#异步调用四大方法详解

开发 后端
C#异步调用四大方法是什么呢?他们各自的作用是什么呢?那么本文就向你介绍C#异步调用四大方法的具体内容。

C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用:

.NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法用于启动C#异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待C#异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。

EndInvoke 方法用于检索C#异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果C#异步调用未完成,EndInvoke 将一直阻塞到C#异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 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 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。

· 轮询由 BeginInvoke 返回的 IAsyncResult,确定C#异步调用何时完成,然后调用 EndInvoke。

· 将用于回调方法的委托传递给 BeginInvoke。该方法在C#异步调用完成后在 ThreadPool 线程上执行,它可以调用 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)。

  1. using System;  
  2. using System.Threading;   
  3.  
  4. public class AsyncDemo {  
  5. // The method to be executed asynchronously.  
  6. //  
  7. public string TestMethod(  
  8. int callDuration, out int threadId) {  
  9. Console.WriteLine("Test method begins.");  
  10. Thread.Sleep(callDuration);  
  11. threadId = AppDomain.GetCurrentThreadId();  
  12. return "MyCallTime was " + callDuration.ToString();  
  13. }  
  14. }  
  15.  
  16. // The delegate must have the same signature as the method  
  17. // you want to call asynchronously.  
  18. public delegate string AsyncDelegate(  
  19. int callDuration, out int threadId);  
  20.    
  21.  
  22. using System;  
  23. using System.Threading;   
  24.  
  25. public class AsyncDemo {  
  26. // The method to be executed asynchronously.  
  27. //  
  28. public string TestMethod(  
  29. int callDuration, out int threadId) {  
  30. Console.WriteLine("Test method begins.");  
  31. Thread.Sleep(callDuration);  
  32. threadId = AppDomain.GetCurrentThreadId();  
  33. return "MyCallTime was " + callDuration.ToString();  
  34. }  
  35. }  
  36.  
  37. // The delegate must have the same signature as the method  
  38. // you want to call asynchronously.  
  39. public delegate string AsyncDelegate(  
  40. int callDuration, out int threadId); 

C#异步调用四大方法之使用 EndInvoke 等待异步调用

异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到C#异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。

  1. public class AsyncMain {  
  2. static void Main(string[] args) {  
  3. // The asynchronous method puts the thread id here.  
  4. int threadId;  
  5.  
  6. // Create an instance of the test class.  
  7. AsyncDemo ad = new AsyncDemo();  
  8.  
  9. // Create the delegate.  
  10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
  11.      
  12. // Initiate the asychronous call.  
  13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
  14. out threadId, nullnull);  
  15.  
  16. Thread.Sleep(0);  
  17. Console.WriteLine("Main thread {0} does some work.",  
  18. AppDomain.GetCurrentThreadId());  
  19.  
  20. // Call EndInvoke to Wait for   
  21. //the asynchronous call to complete,  
  22. // and to retrieve the results.  
  23. string ret = dlgt.EndInvoke(out threadId, ar);  
  24.  
  25. Console.WriteLine("The call executed on thread {0},   
  26. with return value \"{1}\".", threadId, ret);  
  27. }  

C#异步调用四大方法之使用 WaitHandle 等待异步调用

等待 WaitHandle 是一项常用的线程同步技术。您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 属性来获取 WaitHandle。C#异步调用完成时会发出 WaitHandle 信号,而您可以通过调用它的 WaitOne 等待它。

如果您使用 WaitHandle,则在C#异步调用完成之后,但在通过调用 EndInvoke 检索结果之前,可以执行其他处理。

  1. public class AsyncMain {  
  2. static void Main(string[] args) {  
  3. // The asynchronous method puts the thread id here.  
  4. int threadId;  
  5.  
  6. // Create an instance of the test class.  
  7. AsyncDemo ad = new AsyncDemo();  
  8.  
  9. // Create the delegate.  
  10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
  11.      
  12. // Initiate the asychronous call.  
  13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
  14. out threadId, nullnull);  
  15.  
  16. Thread.Sleep(0);  
  17. Console.WriteLine("Main thread {0} does some work.",  
  18. AppDomain.GetCurrentThreadId());  
  19.  
  20. // Wait for the WaitHandle to become signaled.  
  21. ar.AsyncWaitHandle.WaitOne();  
  22.  
  23. // Perform additional processing here.  
  24. // Call EndInvoke to retrieve the results.  
  25. string ret = dlgt.EndInvoke(out threadId, ar);  
  26.  
  27. Console.WriteLine("The call executed on thread {0},   
  28. with return value \"{1}\".", threadId, ret);  
  29. }  

C#异步调用四大方法之轮询异步调用完成

您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性来发现C#异步调用何时完成。从用户界面的服务线程中进行C#异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。

  1. public class AsyncMain {  
  2. static void Main(string[] args) {  
  3. // The asynchronous method puts the thread id here.  
  4. int threadId;  
  5.  
  6. // Create an instance of the test class.  
  7. AsyncDemo ad = new AsyncDemo();  
  8.  
  9. // Create the delegate.  
  10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
  11.      
  12. // Initiate the asychronous call.  
  13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
  14. out threadId, nullnull);  
  15.  
  16. // Poll while simulating work.  
  17. while(ar.IsCompleted == false) {  
  18. Thread.Sleep(10);  
  19. }  
  20.  
  21. // Call EndInvoke to retrieve the results.  
  22. string ret = dlgt.EndInvoke(out threadId, ar);  
  23.  
  24. Console.WriteLine("The call executed on thread {0},  
  25.  with return value \"{1}\".", threadId, ret);  
  26. }  

C#异步调用四大方法之异步调用完成时执行回调方法

如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法。回调方法在 ThreadPool 线程上执行。

要使用回调方法,必须将代表该方法的 AsyncCallback 委托传递给 BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。

  1. public class AsyncMain {  
  2. // Asynchronous method puts the thread id here.  
  3. private static int threadId;  
  4.  
  5. static void Main(string[] args) {  
  6. // Create an instance of the test class.  
  7. AsyncDemo ad = new AsyncDemo();  
  8.  
  9. // Create the delegate.  
  10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
  11.      
  12. // Initiate the asychronous call.  Include an AsyncCallback  
  13. // delegate representing the callback method, and the data  
  14. // needed to call EndInvoke.  
  15. IAsyncResult ar = dlgt.BeginInvoke(3000,  
  16. out threadId,   
  17. new AsyncCallback(CallbackMethod),  
  18. dlgt );  
  19.  
  20. Console.WriteLine("Press Enter to close application.");  
  21. Console.ReadLine();  
  22. }  
  23.  
  24. // Callback method must have the same signature as the  
  25. // AsyncCallback delegate.  
  26. static void CallbackMethod(IAsyncResult ar) {  
  27. // Retrieve the delegate.  
  28. AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState;  
  29.  
  30. // Call EndInvoke to retrieve the results.  
  31. string ret = dlgt.EndInvoke(out threadId, ar);  
  32.  
  33. Console.WriteLine("The call executed on thread {0},  
  34.  with return value \"{1}\".", threadId, ret);  
  35. }  
  36. }  

C#异步调用四大方法的基本内容就向你介绍到这里,希望对你了解和学习C#异步调用有所帮助。

【编辑推荐】

  1. FlyTcpFramework在C#异步中的应用
  2. C#异步调用的应用实践浅谈
  3. 委托实现C#异步调用浅析
  4. 浅析C#中异步和多线程的区别
  5. C# Socket通信三大问题详解
责任编辑:仲衡 来源: 博客园
相关推荐

2009-10-20 16:48:30

C#委托

2009-08-21 11:24:16

C#异步调用

2009-08-21 11:02:55

C#异步调用

2009-08-20 19:08:30

C#异步调用

2009-08-28 11:43:26

C#数组初始化

2021-07-30 17:47:46

数据中心电力能源

2021-08-13 09:55:42

数据中心功耗IT支出

2009-08-21 10:17:14

C#异步网络编程

2009-08-17 08:01:00

C#文件列表

2011-11-14 09:58:33

2009-11-06 15:54:15

WCF异步调用

2021-10-21 08:49:36

物联网市场物联网IOT

2021-03-29 09:26:44

SpringBoot异步调用@Async

2010-01-11 17:24:19

VB.NET异步调用

2009-07-23 13:47:46

ASP.NET数据缓存

2009-09-01 09:37:15

C#写文件

2009-09-02 10:49:46

C#调用析构方法

2009-08-17 16:49:46

C#多线程控制

2020-11-13 09:02:35

CIOGartner

2009-01-11 10:25:00

局域网共享上网
点赞
收藏

51CTO技术栈公众号