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;
    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 等待异步调用

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

  1. 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(,
    out threadId, null, null); Thread.Sleep();
    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#异步调用完成时会发出 WaitHandle 信号,而您可以通过调用它的 WaitOne 等待它。

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

  1. 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(,
    out threadId, null, null); Thread.Sleep();
    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 属性来发现C#异步调用何时完成。从用户界面的服务线程中进行C#异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。

  1. 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(,
    out threadId, null, null); // Poll while simulating work.
    while(ar.IsCompleted == false) {
    Thread.Sleep();
    } // 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#异步调用四大方法之异步调用完成时执行回调方法

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

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

  1. 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(,
    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);
    }
    }

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. eclipse常用的快捷键 大全

    1. [ALT +/] 此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ALT +/]快捷键带来的好处吧. 2. [Ct ...

  2. Django之form组件is_valid校验机制

    #先来归纳一下整个流程 #()首先is_valid()起手,看seld.errors中是否值,只要有值就是flase #()接着分析errors.里面判断_errors是都为空,如果为空返回self. ...

  3. MatLab Swap Rows or Cols 交换行或列

    Matlab是矩阵运算的神器,所以可以很轻易的交换任意行或列,而且写法非常简洁,如下所示: a = [ ; ; ]; b = a; b(:,[;]) = b(:,[;]); % Swap col an ...

  4. ubuntu16.04 下 卸载CUDA9.1

    网上很多教程删除都全  安装其他还会出错 在这把它删除,在命令行中输入 sudo apt-get remove cuda sudo apt-get autoclean sudo apt-get rem ...

  5. CSU 1803 - 2016 - [同余]

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1803 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) 的数量: 1. ...

  6. 大数据竞赛平台Kaggle案例实战

    Kaggle是由联合创始人.首席执行官安东尼·高德布卢姆(Anthony Goldbloom)2010年在墨尔本创立的,主要为开发商和数据科学家提供举办机器学习竞赛.托管数据库.编写和分享代码的平台. ...

  7. POJ_3349_Snowflake Snow Snowflakes

    Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 43504   Accep ...

  8. JS和webView的交互

    JSContext的交互方式最为简单快捷: 1.申明一个JSContext对象 self.jsRunner = [[JSContext alloc] init]; 2.在原生中定义申明一个JS函数方法 ...

  9. Visual Studio 2017 调试 windows server 2016 Docker Container

    网上很多文章都是在win10下,用Docker for windows工具进行Docker的安装部署的.用知道windows server 2016已经原生支持Docker了,其windows Con ...

  10. Why String is Immutable or Final in Java

    The string is Immutable in Java because String objects are cached in String pool. Since cached Strin ...