.Net framework可以让你异步调用任何方法,你可以定义一个与你要调用的方法的签名相同的委托。公共语言运行时将自动为该委托定义与签名相同的BeginInvok和EndInvoke方法。

BeginInvoke方法触发你的异步方法,它和你想要执行的异步方法有相同的参数。另外还有两个可选参数,第一个是AsyncCallback委托是异步完成的回调方法。第二个是用户自定义对象,该对象将传递到回调方法中。BeginInvoke立即返回并且不等待完成异步的调用(继续执行该下面的代码,不需要等待)。BeginInvoke返回IAsyncResult接口,可用于检测异步调用的过程。

通过EndInvoke方法检测异步调用的结果。如果异步调用尚未完成,EndInvoke将阻塞调用线程,直到它完成

下面代码演示使用BeginInvoke和EndInvoke进行异步调用的四种常见方式。在调用BeginInvoke可以做以下工作:

  • 做一些其他操作,然后调用EndInvoke方法阻塞线程直到该方法完成。
  • 使用IAsyncResult.AsyncWaitHandle属性,使用它的WaitOne方法阻塞线程直到收到WaitHandle信号,然后调用EndInvoke。
  • 检查BeginInvoke返回值IAsyncResult的状态来决定方法是否完成,然后调用EndInvoke方法。
 public delegate string AsyncMethodCaller(int callDuration, out int threadId);
class Program
{
static void Main(string[] args)
{ }
static string TestMethod(int callDuration, out int threadId)
{
Console.WriteLine("Test method begins:");
//睡一会 模拟耗时操作
Thread.Sleep(callDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
return string.Format("My call time was {0}.", callDuration.ToString());
}
}

情况一:通过EndInovke阻塞线程,直到异步调用结束。

 static void Main(string[] args)
{
int threadId;
AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod);
IAsyncResult result = caller.BeginInvoke(, out threadId, null, null);
//调用EndInvoke方法,等待异步嗲用完成,并得到结果。
string returnValue = caller.EndInvoke(out threadId, result);
Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue);
Console.Read();
}

情况二:通过WaitHandle属性阻塞线程。

static void Main(string[] args)
{
int threadId;
AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod);
IAsyncResult result = caller.BeginInvoke(, out threadId, null, null);
Thread.Sleep();
Console.WriteLine("Main thread {0} does some work.", Thread.CurrentThread.ManagedThreadId);
//等待WaitHandle信号
result.AsyncWaitHandle.WaitOne();
//调用EndInvoke方法,等待异步嗲用完成,并得到结果。
string returnValue = caller.EndInvoke(out threadId, result);
//关闭等待句柄
result.AsyncWaitHandle.Close();
Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue);
Console.Read();
}

情况三:检查BeginInvoke返回结果的状态。

可以通过BeginInvoke的返回结果的IsCompleted属性检查异步是否完成。你可以在异步没有完成的时候做其他的操作。

static void Main(string[] args)
{
int threadId;
AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod);
IAsyncResult result = caller.BeginInvoke(, out threadId, null, null);
Thread.Sleep();
Console.WriteLine("Main thread {0} does some work.", Thread.CurrentThread.ManagedThreadId);
while (result.IsCompleted == false)
{
Thread.Sleep();
Console.WriteLine("*");
}
//调用EndInvoke方法,等待异步嗲用完成,并得到结果。
string returnValue = caller.EndInvoke(out threadId, result);
//关闭等待句柄
result.AsyncWaitHandle.Close();
Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue);
Console.Read();
}

情况4、可以使用回调函数。

private delegate string RunOnThreadPool(out int threadId);

        private static void Callback(IAsyncResult ar)
{
Console.WriteLine("开始回调方法");
Console.WriteLine("回调方法的参数: {0}", ar.AsyncState);
Console.WriteLine("是否线程池: {0}", Thread.CurrentThread.IsThreadPoolThread);
Console.WriteLine("线程池线程 id: {0}", Thread.CurrentThread.ManagedThreadId);
} private static string Test(out int threadId)
{
Console.WriteLine("Starting...");
Console.WriteLine("是否线程池: {0}", Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds());
threadId = Thread.CurrentThread.ManagedThreadId;
return string.Format("线程池线程 id 是: {0}", threadId);
}

回调函数的执行,是在EndInvoke之后执行的。

(二)异步方法BeginInvoke和EndInvoke的更多相关文章

  1. c#委托中的同步和异步方法即BeginInvoke和EndInvoke

    学习多线程之前我们先了解一下电脑的一些概念,比如进程,线程,这个参考https://www.cnblogs.com/loverwangshan/p/10409755.html 这篇文章.今天我们接着来 ...

  2. C#线程系列讲座(1):BeginInvoke和EndInvoke方法

    一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...

  3. [转]BeginInvoke和EndInvoke方法浅析

    开发语言:C#3.0   IDE:Visual Studio 2008   一.C#线程概述   在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提 ...

  4. delegate 中的BeginInvoke和EndInvoke方法

    开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能 ...

  5. 转:C#线程系列讲座(1) BeginInvoke和EndInvoke方法

    转载自:http://www.cnblogs.com/levin9/articles/2319248.html 开发语言:C#3.0IDE:Visual Studio 2008本系列教程主要包括如下内 ...

  6. 黄聪:C#多线程教程(1):BeginInvoke和EndInvoke方法,解决主线程延时Thread.sleep柱塞问题(转)

    开发语言:C#3.0 IDE:Visual Studio 2008 本系列教程主要包括如下内容: 1.  BeginInvoke和EndInvoke方法 2.  Thread类 3. 线程池 4. 线 ...

  7. C# BeginInvoke和EndInvoke方法

    转载自:BeginInvoke和EndInvoke方法 IDE:Visual Studio 2008 本系列教程主要包括如下内容:1. BeginInvoke和EndInvoke方法 2. Threa ...

  8. C#线程 BeginInvoke和EndInvoke使用方法

    一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...

  9. C#线程应用实例(part1) 之 BeginInvoke和EndInvoke

    最近这个公司是做 winfrom 开发的 , 这段时间就好好的学学WCF , 公司框架什么的自己去琢磨! 这里主要写一些 winfrom 中 用到的一些陌生 技术 1.BeginInvoke  以前B ...

随机推荐

  1. 算法-java代码实现插入排序

    插入排序  

  2. ThinkPHP3.2 实现Mysql数据库备份

    <?php header("Content-type:text/html;charset=utf-8"); //配置信息 $cfg_dbhost = 'localhost'; ...

  3. Uva 12171 Sculpture - 离散化 + floodfill

    题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  4. <%=pageCount %>

    <%=pageCount %>,这里是指获取页面控件的值.

  5. Java数据持久层框架 MyBatis之API学习二(入门)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  6. ASP.NET Core 一步步搭建个人网站(6)_单页模式和优化

    前言 HI,有段时间没有更新了,主要因为第一年前事情比较多,有些事得忙着张罗下:第二呢,对个人网站进行了一次大范围的优化,主要是申请的云服务器资源有限,1m的网络带宽,带上图片展示的话,打开网站的平均 ...

  7. Do you know how many stuff inside your Google Account?

    My friend Sandy she wants me to do her a favor. She'd like to clear Hangouts chat history. I think s ...

  8. scipy.optimize.minimize 解决实际问题

    接上博客问题http://www.cnblogs.com/shizhenqiang/p/8274806.html # coding=utf-8 from scipy import optimize i ...

  9. _3_body_标签

    创:20_3_2017修:5_4_2017 什么是div标签? div 双 -- div标签没有任何默认属性 -可以任意写入样式和内容,和 水一样,水自然平凡而又最多 什么是h1标签? h1 标题(双 ...

  10. linux ssh登录的小知识

    查看服务器的各个端口: # netstat -tulnp 或者 #netstat -tnip 筛选在后面添加 |grep *** 准许root登录 #vi /etc/ssh/sshd_config 找 ...