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. using System;
    22. using System.Threading;
    23.  
    24. public class AsyncDemo {
    25. // The method to be executed asynchronously.
    26. //
    27. public string TestMethod(
    28. int callDuration, out int threadId) {
    29. Console.WriteLine("Test method begins.");
    30. Thread.Sleep(callDuration);
    31. threadId = AppDomain.GetCurrentThreadId();
    32. return "MyCallTime was " + callDuration.ToString();
    33. }
    34. }
    35.  
    36. // The delegate must have the same signature as the method
    37. // you want to call asynchronously.
    38. public delegate string AsyncDelegate(
    39. 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(,
    14. out threadId, null, null);
    15.  
    16. Thread.Sleep();
    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. }
    28. }

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(,
    14. out threadId, null, null);
    15.  
    16. Thread.Sleep();
    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. }
    30. }

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(,
    14. out threadId, null, null);
    15.  
    16. // Poll while simulating work.
    17. while(ar.IsCompleted == false) {
    18. Thread.Sleep();
    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. }
    27. }

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(,
    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#异步调用有所帮助。

[转载]C#异步调用四大方法详解的更多相关文章

  1. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

  2. Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)

    Python 在子类中调用父类方法详解(单继承.多层继承.多重继承)   by:授客 QQ:1033553122   测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...

  3. C#中异步调用示例与详解

    using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...

  4. vc中调用Com组件的方法详解

    vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGet ...

  5. Clone使用方法详解【转载】

    博客引用地址:Clone使用方法详解 Clone使用方法详解   java“指针”       Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文 ...

  6. Python调用C/C++动态链接库的方法详解

    Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...

  7. 转载 JS组件Bootstrap Select2使用方法详解

    JS组件Bootstrap Select2使用方法详解 作者:懒得安分 字体:[增加 减小] 类型:转载 时间:2016-01-26我要评论 这篇文章主要为大家介绍了JS组件Bootstrap Sel ...

  8. php调用C代码的方法详解和zend_parse_parameters函数详解

    php调用C代码的方法详解 在php程序中需要用到C代码,应该是下面两种情况: 1 已有C代码,在php程序中想直接用 2 由于php的性能问题,需要用C来实现部分功能   针对第一种情况,最合适的方 ...

  9. Android笔记——四大组件详解与总结

     android四大组件分别为activity.service.content provider.broadcast receiver. ------------------------------- ...

随机推荐

  1. CmD空格转义的三种方法,总有一种会解决问题

    CmD空格转义 在cmd中,如果路径中存在空格报错 可以有三种解决方法: 1.将存在空格的路径用双引号包起来,如:"D:/Program Files/xx"; 2.将存在空格的名称 ...

  2. java中List的toArray方法

    把List转换成某种类型的数组,就拿String类型来做例子吧,有以下两种方式: //方法1,使用不带参数的toArray方法 String[] arr1=new String[list.size() ...

  3. poj3304 Segments【计算几何】

    C - Segments POJ - 3304 最近开始刷计算几何了 公式好多完全不会 数学不行 几何不行 记忆力不行 当机 查的题解 就当复习吧 这套专题拿来熟悉一下计算几何模板 #include ...

  4. 初次安装hive-2.1.0启动报错问题解决方法

    首次安装hive-2.1.0,通过bin/hive登录hive shell命令行,报错如下: [hadoop@db03 hive-2.1.0]$ bin/hive which: no hbase in ...

  5. The Concept of a Process

    COMPPUTER SCIENCE AN OVERVIEW 11th Edition One of the most fundamental concepts of modern operating ...

  6. iOS多线程编程之GCD的基本使用(转载)

    一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同 ...

  7. Find a way--hdu2612

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2612 广搜题 注意:可能存在一个@两人都不能达到: 3 3 Y#@ .M# @.. #include ...

  8. 《javascript算法--对象的比较》

    方法一:JSON.stringify() 此方法简单,适用于当两个对象的属性顺序相同的时候. var user1 = {name : "nerd", org: "dev& ...

  9. Failed to load project at 'xxx.xcodeproj', incompatible project version。

    Failed to load project at 'xxx.xcodeproj', incompatible project version. 更新最新的xcode,xcode高版本可以打开低版本的 ...

  10. vertx打成jar包发布工程,访问静态页面

    1:添加pom依赖,配置打包插件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="htt ...