本文参考自C#基础:线程之异步回调(委托),纯属读书笔记

在解析异步回调之前,先看同步回调的执行过程,以及代码原理。

1、线程的同步执行

同步执行:在主线程执行的时候,主线程调用一个其它方法,此时主线程阻塞,等待调用方法执行完成后主线程才能继续执行。

代码如下:

    class Program
{
static void Main(string[] args)
{
for (int i = ; i < ; i++) {
if (i == ) {
Console.WriteLine("调用TakeAWhile方法并等待其执行完成");
Console.WriteLine("开始执行TakeAWhile方法,时间:{0}", DateTime.Now);
int result = TakeAWhile(, );
if (result == ) {
Console.WriteLine("TakeAWhile方法执行完成");
}
Console.WriteLine("TakeAWhile方法执行完毕,时间:{0}", DateTime.Now);
}
Thread.Sleep();
Console.WriteLine(i.ToString());
}
}
static int TakeAWhile(int data, int time) {
Thread.Sleep(time);
return ++data;
}
}

从上面的结果得出当程序开始调用TakeAWhile方法后,主线程阻塞,当TakeAWhile方法调用完毕之后,主线程又重新开始运行,这个过程就是线程的同步执行的过程.

2、线程的异步执行

what is 异步执行?

异步执行:在主线程执行的时候,打开一个子线程,主线程不会像同步执行的那样等待子线程的结果返回后在执行,主线程会继续执行,当主线程需要子线程的运行结果时,主线程直接调用子线程的运行结果,如果子线程的运行结果还没有出来,那么主线程等待,直到子线程执行结束,主线程拿到子线程的运行结果,主线程在继续。

 class Program
{
static void Main(string[] args)
{
Func<int, int, int> fun = TakeAWhile;
IAsyncResult ar = fun.BeginInvoke(, , null, null);//主线程调用子线程开始执行TakeAWhile方法,并给它传递了参数
int times=;
while (!ar.IsCompleted)
{
//当子线程没有完成之前,主线程可以在该while语句块内进行任何后续操作,而且不用等待子线程的结束
Console.WriteLine(times++);
Thread.Sleep();
}
int result = fun.EndInvoke(ar);//1秒之后我需要子线程的结果了,ok,从子线程中拿到结果
Console.WriteLine("TakeAWhile方法结束,时间是:{0}", DateTime.Now);
Console.WriteLine("result:{0}", result);
Console.ReadKey();
} static int TakeAWhile(int data, int times)
{
Console.WriteLine("TakeAWhile方法开始执行,时间是:{0}",DateTime.Now);
Thread.Sleep(times);
return ++data;
}
}

从结果和代码进行分析,当通过BeginInvoke方法开始异步执行TakeAWhile方法,主线程继续执行,然后通过IsCompleted属性判断TakeAWhile是否执行完成,最后获取子线程的输出值,并输出其结果,整个过程主线程没有因为在执行子线程的原因,而造成阻塞

注:因为多线程,导致了这个情况,开启子线程和执行子线程中的方法都需要时间,所以主线程的执行速度快于子线程,所以先输出了一个1;解决方法很简单,让主线程休息一会,等子线程先初始化完,代码如下:

class Program
{
static void Main(string[] args)
{
Func<int, int, int> fun = TakeAWhile;
IAsyncResult ar = fun.BeginInvoke(, , null, null);//主线程调用子线程开始执行TakeAWhile方法,并给它传递了参数
Thread.Sleep();//休息一会
int times=;
while (!ar.IsCompleted)
{
//当子线程没有完成之前,主线程可以在该while语句块内进行任何后续操作,而且不用等待子线程的结束
Console.WriteLine(times++);
Thread.Sleep();
}
int result = fun.EndInvoke(ar);//6秒之后我需要子线程的结果了,ok,从子线程中拿到结果
Console.WriteLine("TakeAWhile方法结束,时间是:{0}", DateTime.Now);
Console.WriteLine("result:{0}", result);
Console.ReadKey();
} static int TakeAWhile(int data, int times)
{
Console.WriteLine("TakeAWhile方法开始执行,时间是:{0}",DateTime.Now);
Thread.Sleep(times);
return ++data;
}
}

3、异步回调

what is 异步异步回调?

异步回调:主线程在执行的时候,打开一个子线程,主线程继续执行,当子线程执行完成的时候,主线程立即输出子线程的运行结果,主线程继续执行。

class Program
{
static void Main(string[] args)
{
Func<int, int, int> fun = TakeAWhile;
fun.BeginInvoke(, , TakesAWhileCallBack, fun);//异步调用TakeAWhile,并指定回调函数TakesAWhileCallBack
for (int i = ; i < ; i++)
{
Console.WriteLine(i.ToString());
Thread.Sleep();
}
Console.ReadKey();
}
static int TakeAWhile(int data, int times) {
Console.WriteLine("TakeAWhile方法开始执行,时间是:{0}", DateTime.Now);
Thread.Sleep(times);
return ++data;
}
/// <summary>
/// 回调函数
/// </summary>
/// <param name="fun">调用的委托</param>
static void TakesAWhileCallBack(IAsyncResult fun)
{
if (fun == null)
throw new ArgumentNullException("fun");
Func<int, int, int> dl = (Func<int, int, int>)fun.AsyncState;
int result = dl.EndInvoke(fun);
Console.WriteLine("我是回调函数返回的结果:{0}", result);
Console.WriteLine("TakeAWhile执行完成,时间是:{0}", DateTime.Now);
}
}

C# 多线程系列之异步回调(委托)的更多相关文章

  1. Android进阶——多线程系列之异步任务AsyncTask的使用与源码分析

    AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并主线程中更新UI,通过AsyncTask可以更加方便执行后台任务以及在主线程中访问UI ...

  2. AsyncCallback 异步回调委托

    js是单线程语言,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务.如果前一个任务耗时很长,后一个任务就不得不一直等着. 如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多 ...

  3. .Net进阶系列(11)-异步多线程(委托BeginInvoke)(被替换)

    一. BeginInvoke最后两个参数的含义 倒数第二个参数:指该线程执行完毕后的回调函数:倒数第一个参数:可以向回调函数中传递参数. 下面以一段代码说明: /// <summary> ...

  4. 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)

    一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并 ...

  5. C# 同步调用 异步调用 异步回调 多线程的作用

    同步调用   : 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 异步调用  :同步调用会阻塞线程,如果是要调用一项繁重的 ...

  6. C# 多线程操作之异步委托

    标签: 多线程任务nullstringhtml工作 2012-06-29 23:00 1276人阅读 评论(0) 收藏 举报  分类: C/C++/C#/dotnet(126)    目录(?)[+] ...

  7. c#线程之异步委托begininvoke、invoke、AsyncWaitHandle.WaitOne 、异步回调

    单靠自己看书学总是会走很多弯路,任何人也不列外,有些时候自己遇到的很多问题,其它别人在很久之前也可能遇到过,上网查查可以走很大捷径,对自己的学习有很大帮助,刚开始弄线程这块,一开始只是看书,很多东西都 ...

  8. 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)

    下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...

  9. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class ...

随机推荐

  1. java多线程 基础demo

    join()   让主进程等待子进程全部执行完 例子如下:   package mocker; public class TestThread5 extends Thread {      priva ...

  2. mysql设定或修改密码的三个方法

    为用户设定密码: 1.mysql>SET PASSWORD FOR 'USERNAME'@'HOST'=PASSWORD('password'); 2.# mysqladmin -uUSERNA ...

  3. leetcode 合并两个有序数组

    给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: - 初始化 nums1 和 nums2 的元素数量分别为 m 和 ...

  4. C++ 模板和 C# 泛型之间的区别(C# 编程指南)

    C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能. 然而,这两者之间存在许多差异. 在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性. 此外,C# 并不 ...

  5. Algebraic Foundations ( Arithmetic and Algebra) CGAL 4.13 -User Manual

    理解: 本节主要介绍CGAL的代数结构和概念之间的互操作.与传统数论不同,CGAL的代数结构关注于实数轴的“可嵌入”特征.它没有将所有传统数的集合映射到自己的代数结构概念中,避免使用“数的类型”这一术 ...

  6. C# winform中listview排序

    本文解决方案是采用下面链接中的解决方案.十分感谢这篇文章的作者bright:http://blog.163.com/shensc@126/blog/static/1312896522010614103 ...

  7. JAVA构造函数(方法)

    一.什么是构造函数 java构造函数,也叫构造方法,是java中一种特殊的函数.函数名与相同,无返回值. 作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象了属性和方法. 在现 ...

  8. django 的 安全机制

    xss 保护: xss攻击允许用户注入客户端脚本到其他用户的服务器上.通常通过存储恶意脚本到数据库,其他用户通过数据库获取恶意脚本,并在浏览器上呈现:或是使用户点击会引起攻击者javascirpt脚本 ...

  9. Eclipse署动态web项目方法

    和MyEclipse不一样,在Eclipse中做的Web项目默认是不支持将项目发布到Web服务器上的,会发布到工作空间的某个目录,因此无法在外部启动Tomcat来运行Web项目,只有打开Eclipse ...

  10. /proc/xxx/maps简要记录

    定位内存泄漏基本上是从宏观到微观,进而定位到代码位置. 从/proc/meminfo可以看到整个系统内存消耗情况,使用top可以看到每个进程的VIRT(虚拟内存)和RES(实际占用内存),基本上就可以 ...