(二)异步方法BeginInvoke和EndInvoke
.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的更多相关文章
- c#委托中的同步和异步方法即BeginInvoke和EndInvoke
学习多线程之前我们先了解一下电脑的一些概念,比如进程,线程,这个参考https://www.cnblogs.com/loverwangshan/p/10409755.html 这篇文章.今天我们接着来 ...
- C#线程系列讲座(1):BeginInvoke和EndInvoke方法
一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...
- [转]BeginInvoke和EndInvoke方法浅析
开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提 ...
- delegate 中的BeginInvoke和EndInvoke方法
开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能 ...
- 转:C#线程系列讲座(1) BeginInvoke和EndInvoke方法
转载自:http://www.cnblogs.com/levin9/articles/2319248.html 开发语言:C#3.0IDE:Visual Studio 2008本系列教程主要包括如下内 ...
- 黄聪:C#多线程教程(1):BeginInvoke和EndInvoke方法,解决主线程延时Thread.sleep柱塞问题(转)
开发语言:C#3.0 IDE:Visual Studio 2008 本系列教程主要包括如下内容: 1. BeginInvoke和EndInvoke方法 2. Thread类 3. 线程池 4. 线 ...
- C# BeginInvoke和EndInvoke方法
转载自:BeginInvoke和EndInvoke方法 IDE:Visual Studio 2008 本系列教程主要包括如下内容:1. BeginInvoke和EndInvoke方法 2. Threa ...
- C#线程 BeginInvoke和EndInvoke使用方法
一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...
- C#线程应用实例(part1) 之 BeginInvoke和EndInvoke
最近这个公司是做 winfrom 开发的 , 这段时间就好好的学学WCF , 公司框架什么的自己去琢磨! 这里主要写一些 winfrom 中 用到的一些陌生 技术 1.BeginInvoke 以前B ...
随机推荐
- Putty(菩提)远程连接服务器教程听语音
Putty是一款优秀的免费串行接口连接软件,由于其绿色和性能深受业界好评,绿色是指putty使用便捷只需要将putty下载到电脑,无需安装,只需要在电脑上新建一个快捷方式就可以使用.出色的性能是指pu ...
- SSH会话连接超时问题
目前大多数ssh服务是运行在Linux系统上的sshd服务.当访问终端在windows上时,各终端软件,如,putty,SecureCRT等,大多支持设置向服务器端自动发送消息,来防止终端定期超时.其 ...
- Tp-link路由器怎么设置端口映射 内网端口映射听语音
https://jingyan.baidu.com/article/ca00d56c710ef9e99eebcf85.html 只有一台能上网的电脑就可以自己免费搭建服务器,本经验简单介绍家用tp-l ...
- destoon 默认广告位代码
<img src="http://www.testinstrument.cn/skin/default/jiurong/img/banner.png" alt="& ...
- CentOS 7安装
使用U盘安装 1.CentOS 7系统镜像制作U盘启动盘 1).下载CentOS 7系统镜像 下载地址:http://mirrors.aliyun.com/centos/7/isos/x86_64/ ...
- JavaScript高级编程小结
Undefined 对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined var message; console.l ...
- 反应堆模式(reactor)
在提到高性能服务器编程的时候肯定有听过reactor模式,如果只是简单的写一个服务器和客户端建立连接的程序来熟悉一下使用socket函数编程,一般这种情况都是同步方式实现的,服务器阻塞等待客户端的连接 ...
- Python 字符串大小写操作
#coding=utf-8 #python中字符串的操作 # 字符串的大小写 s='hello_wOrld_oF_you' upper_str = s.upper() print('全部大写: ',u ...
- tp5中设置指定的log日志,可单独建立文件夹和文件名
1:在D:\www\tp5\thinkphp\library\think\Log.php中添加下列代码.可在runtime文件夹下建立tlogs文件夹(可自定义). /** * [payLog 支付日 ...
- C++ 指针大小
32 位机: 指针大小 sizeof(void*)4字节,32位.例如:0x12345678 64位机: 指针大小: sizeof(void*)8字节,64位.一般只用48位,指针形如:0x12345 ...