委托之异步

在 使用BackgroundWorker组件 一文中,阐述了在Winform编程中,使用BackgroundWorker组件实现异步调用,本文主要讲述利用委托实现异步。

以下描述摘抄于MSDN:

异步委托提供以异步方式调用同步方法的能力。

当同步调用委托时,Invoke()方法直接对当前线程调用目标方法;

当异步调用委托时,CLR将对请求进行排队并立即返回到调用方,将对来自线程池的线程调用该目标方法,提交请求的原始线程继续与目标方法并行执行,该目标方法是对线程池线程运行的.

1)、BeginInvoke()方法

BeginInvoke()方法启动异步调用,它与需要异步执行的方法具有相同的参数。

另外,还有两个可选参数:第一个参数是AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第二个参数是用户定义的对象,该对象可向回调方法传递信息;

BeginInvoke立即返回,不等待异步调用完成;

BeginInvoke返回IAsyncResult,这个结果可用于监视异步调用的进度;

2)、EndInvoke()方法

EndInvoke()方法检索异步调用的结果;

在调用BeginInvoke()方法后,可以随时调用EndInvoke()方法,如果异步调用尚未完成,则EndInvoke()方法将一直阻止调用线程,直到异步调用完成后才允许调用线程执行;

EndInvoke()的参数需要异步执行的方法的out和ref参数以及由BeginInvoke()返回的IAsyncResult。

 

下面通过代码阐述异步委托:

代码一,同步执行:
 public delegate int MathDelegate(int x);    
public class MathClass
{
public int Add(int x)
{
Thread.Sleep(10000);//此处模拟长时间执行的任务
return x + x;
}
}

public class Program
{
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

//同步执行
int syncResult = mathDel(8);
Console.WriteLine("Sync Proccessing operation...");//这一行只有SyncMethod完成以后才能显示
Console.WriteLine("Sync Result is: {0}", syncResult);

Console.ReadLine();
}
}
当程序执行到 int syncResult = mathDel(8); 的时候,主线程将等待至少10秒的时间(Add方法的执行),才能执行
后面的代码,也即在期间,应用程序没有响应,不能执行其他的任何操作,直到Add方法返回结果。
代码二,异步执行:

我们稍微修改一下Main的代码:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt);

Console.ReadLine();
}

在这段代码中,在开始并没有直接调用方法,而是使用BeginInvoke()方法,返回IAsyncResult 对象。

代码三,IsCompleted,轮询异步调用完成
使用IAsyncResult实例的IsCompleted属性,以获取异步操作是否已完成的指示,如果操作完成则为True,否则为False。

修改一下Main的代码:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备

int i = 1;
while (async.IsCompleted==false)
{
Thread.Sleep(i * 1000);
Console.WriteLine("IsCompleted:{0},{1}", async.IsCompleted, i);
i++;
}
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt);

Console.ReadLine();
}
代码四,AsyncCallback,异步调用完成时执行回调方法

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

如果要使用回调方法,必须将引用回调方法AsyncCallback委托传递给BeginInvoke()方法,也可以传递包含回调方法将要使用的信息的对象。

修改一下Main的代码:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, new AsyncCallback(CompleteMethod), "信息来自于主线程");//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
Console.ReadLine();
}
private static void CompleteMethod(IAsyncResult async)
{
AsyncResult ar = (AsyncResult)async;

MathDelegate del = (MathDelegate)ar.AsyncDelegate;
int result = del.EndInvoke(async);

string mainTheadMsg = ar.AsyncState as string;
Console.WriteLine("{0}, Result is: {1}", mainTheadMsg, result);
}
Add方法调用完成以后,调用 CompleteMethod 方法
结束

转载于:https://www.cnblogs.com/inforasc/archive/2009/10/21/1587756.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[NOI2010]超级钢琴 主席树

[NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样。 堆维护n个左端点&#xff0c;每次取出来再放回去次 代码 #include <bits/stdc.h> #define ll long long using namespace std; const int _5e57,INF0x3f3f3f3f; int read() {int x0,f1;char sgetchar();fo…

【MSP430单片机】IIC 篇

一、转载于:https://www.cnblogs.com/wangsure/p/10734745.html

纹理文本

前面的话 本文将通过多种方式实现纹理文本的效果 背景裁切 对于实现纹理文本的效果&#xff0c;脑海中最直接能想到的办法可能是背景裁切background-clip 使用线性渐变来填充文本背景 <style>.box-with-text { background-image: linear-gradient(135deg,hsl(50, 100%, 7…

ORACLE EXP/IMP 说明

Oracle 的导出导入是一个很常用的迁移工具。 在Oracle 10g中&#xff0c;Oracle 推出了数据泵(expdp/impdp). 它可以通过使用并行&#xff0c;从而在效率上要比exp/imp 要高。 在Oracle 10g和11g的官方文档里没有搜到有关exp/imp 的说明&#xff0c; 在9i里找到了相关的使用说…

JAXB –新手的观点,第1部分

我知道你们很多人已经在想什么了&#xff0c;所以让我们摆脱它&#xff1a;“ JAXB&#xff1f; 如XML&#xff1f; 来吧&#xff0c;所有很棒的孩子都在使用JSON。” 关于XML与JSON的争论以及许多促成它的论据都已被很好地记录在案。 我不会花很多时间在这里重新整理它们。 我…

初识C语言(五)

自定义函数 C语言提供了大量的库函数&#xff08;右侧资料下载中有&#xff09;&#xff0c;比如stdio.h提供输出函数&#xff0c;但是还是满足不了我们开发中的一些逻辑&#xff0c;所以这个时候需要自己定义函数&#xff0c;自定义函数的一般形式&#xff1a; 注意&#xff1…

bzoj2916: [Poi1997]Monochromatic Triangles 思路

bzoj2916: [Poi1997]Monochromatic Triangles 链接 bzoj 思路 总方案\(C_{n}^{3}-异色三角形\) 异色三角形有个特点。 会出现两个点有两条不同色的边。 然后统计就行了。 代码 #include <bits/stdc.h> #define ll long long using namespace std; const int _5e37; int n…

nodeJS实现简单网页爬虫功能

前面的话 本文将使用nodeJS实现一个简单的网页爬虫功能 网页源码 使用http.get()方法获取网页源码&#xff0c;以hao123网站的头条页面为例 http://tuijian.hao123.com/hotrank var http require(http);http.get(http://tuijian.hao123.com/hotrank,function(res){var data ;…

不能上网原因(查)

实验室不能上网原因记录&#xff1a;如果不是你电脑原因&#xff0c;很可能就是路由器和dns设置的问题。。把dns设置为寝室校园网专用dns试试可能就好了。。 网页打不开&#xff0c;浏览器打不开&#xff0c;这是上网时候广大网友经常碰见的问题&#xff0c;本文将针对网页打不…

JavaFX技巧6:使用透明颜色

为用户界面元素选择正确的颜色始终是一个很大的挑战&#xff0c;但是当您开发可重用的框架控件时&#xff0c;开发人员就无法控制使用它们的应用程序的外观和感觉&#xff0c;这甚至更具挑战性。 尽管您可能总是将元素添加到默认的灰色背景之上&#xff0c;但是嵌入控件的开发人…

bzoj2287【POJ Challenge】消失之物 缺一01背包

bzoj2287【POJ Challenge】消失之物 缺一01背包 链接 bzoj 思路 分治solve(l,r,arr)表示缺少物品\([l,r]\)的dp数组arr。 然后solve(l,mid,arr)用右边的物品更新&#xff0c;solve(mid1,r,arr)同理。 \(f(n)2*f(\frac{n}{2})(r-l1)*m\) 复杂度为\(O(nmlog{n})\) 缺点最短路也是…

38.QT-QAxObject快速写入EXCEL示例

参考链接: https://blog.csdn.net/czyt1988/article/details/52121360 http://blog.sina.com.cn/s/blog_a6fb6cc90101gv2p.html 1. QAxObject介绍 在QT中,有个自带的QAxObject类,可以直接操作EXCEL 除此之外,当我们操作某个文件夹下的EXCEL的时候,都会在该文件夹下出现一个隐藏…

EA常见画图(类图、包图、构件图、状态图、顺序图、活动图)

EA常见活动图&#xff0c;状态图画法 类图:111&#xff08;1&#xff09;给关系添加注释&#xff08;2&#xff09;设置关系线样式 包图&#xff1a;&#xff08;1&#xff09;创建包图&#xff08;2&#xff09;在包中添加子包&#xff1a;&#xff08;3&#xff09;在包中添加…

比萨问题–建造者与装饰者

问题陈述 我们需要为一家披萨公司构建软件&#xff0c;该公司想要准备各种类型的披萨&#xff0c;例如鸡肉披萨&#xff0c;扁平面包&#xff0c;意大利辣香肠披萨和额外的奶酪&#xff0c;并在上面放些配料。 让我们尝试看看哪种设计模式适合该问题说明以及在哪种情况下。 传…

系统启动

1.开机2.bios加电自检power on self test 由于此时显卡还未初始化&#xff0c;只能靠声音辨别错误3.将boot sector读入0000&#xff1a;7c00处4.检查0000&#xff1a;7def是否等于0xaa555.跳转到0000&#xff1a;7c00处执行MBR程序6.MBR将自己复制到0000&#xff1a;0600处执行…

bzoj3589 动态树 求链并 容斥

bzoj3589 动态树 链接 bzoj 思路 求链并。 发现只有最多5条链子&#xff0c;可以容斥。 链交求法&#xff1a;链顶是两条链顶深度大的那个&#xff0c;链底是两个链底的\(lca\) 如果链底深度小于链顶&#xff0c;就说明两条链没有交集。 复杂度\(m*2^klog^2n\) 还有一种做法。 …

NodeJS学习目录

前面的话 几年前&#xff0c;对于学习NodeJS可能还有所迟疑&#xff0c;怕分散了前端学习的精力。但到了现在&#xff0c;如果不学习nodeJS&#xff0c;前端的学习却可能无法再有所进展。技术的进步就是这么残酷。对新技术观望的时候&#xff0c;该技术已经大行其道了 小火柴将…

最佳加法表达式

题意&#xff1a;有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中&#xff0c;值最小的那个表达式的值是多少。输入&#xff1a;5 31 2 3 4 5输出&#xff1a;24 1 #include<iostream>2 #include<algorithm>3 using namespa…

我最喜欢的IntelliJ IDEA功能

我已经是IntelliJ IDEA的长期用户&#xff08;和客户&#xff09;。 我想我是在2005年或2006年&#xff08;版本5.0&#xff09;左右开始使用它的。 那时我是Eclipse用户。 我的一些同事向我推荐了它&#xff0c;起初我没有被说服&#xff0c;但是在尝试之后我印象深刻。 现在…

[转载]PHP 计算时间差

我们常常在网站上看到某篇文章发表于“3天前”&#xff0c;“5个月前”&#xff0c;“4年前”。下面这个函数就提供了计算这个时间差的功能。 <?php/*** 时间差计算** param Timestamp $time* return String Time Elapsed* author Shelley Shyan* copyright http://phparch…