创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。

Delegate还支持异步地调用方法。在后台Delegate类会创建一个执行任务的线程。

为了说明委托的异步特性,从一个需要一定的时间才能执行完毕的方法开始。 TakesAWhile方法至少需要经过第2个变量传递的毫秒数才能执行完,因 为它调用了Thread.Sleep()方法。

static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile,start");
Thread.Sleep(ms);
Console.WriteLine("\nTakesAWhile complated");
return ++data;
}

要从委托中调用这个方法 ,必须定义一个有相同参数和返回类型的委托 ,如下面的TakesAWhileDelegate方法所示:

public delegate int TakesAWhileDelegate(int data,int ms);

现在可以使用不同的技术异步地调用委托,并返回结果。

1、投票

static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
IAsyncResult ar = d1.BeginInvoke(1, 5000, null, null);
while (!ar.IsCompleted)
{
Console.Write(".");
Thread.Sleep(50);
} int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
Console.ReadKey();
}

运行结果:

.TakesAWhile,start
................................................
TakesAWhile complated
result:2

2、等待句柄

static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
IAsyncResult ar = d1.BeginInvoke(1, 5000, null, null);
while (true)
{
Console.Write(".");
if (ar.AsyncWaitHandle.WaitOne(50, false))
{
Console.WriteLine("\nCan get the result now");
break;
}
} int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
Console.ReadKey();
}

3、异步回调

class Program
{
public delegate int TakesAWhileDelegate(int data,int ms);
static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
d1.BeginInvoke(1, 3000, TakesAWhileComplated, d1);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}
Console.ReadKey();
} static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile,start");
Thread.Sleep(ms);
Console.WriteLine("\nTakesAWhile complated");
return ++data;
} public static void TakesAWhileComplated (IAsyncResult ar)
{
if (ar == null) throw new ArgumentNullException("ar");
TakesAWhileDelegate d1 = ar.AsyncState as TakesAWhileDelegate;
Trace.Assert(d1 != null, "Invalid object type"); int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
Console.ReadKey();
}
}

运行结果:

.TakesAWhile,start
................................................
TakesAWhile complated
result:2
...................................................

TakesAWhileComplated方法用AsyncCallback委托指定的参数和返回类型来定义 。 用BeginInvoke方法传递的最后一个参数可以使用ar.AsyncState读取。在TakesAWhileDelegate委托中,可以调用EndInvoke方法来获得结果。

注意:使用回调方法,必须注意这个方法从委托的线程中调用,而不是从主线程中调用。

编程模型和所有这些包含异步委托的选项--投票、等待句柄和异步回调--不仅能用于委托。相同的编程模型(即异步模式)在.NET Framework的各个地方都能见到。

例如,可以用HttpWebReques类的BeginGetResponse()方法异步发送HTTP Web请求,使用SqlComand类的BeginExecuteReader()方法给数据库发送异步请求。

这些参数类似于委托的BeginInvoke()方法的参数,也可以使用相同的方式获得结果。

C#基础之--线程、任务和同步:一、异步委托的更多相关文章

  1. spring线程池的同步和异步(1)

    spring线程池(同步.异步) 一.spring异步线程池类图 二.简单介绍 2.1. TaskExecutor---Spring异步线程池的接口类,其实质是java.util.concurrent ...

  2. 4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞

    一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点:  保 ...

  3. 什么是java的线程安全?同步,异步

    线程是比进程更小的执行单位,是在进程基础上进行的进一步划分.所谓多线程是指进程在执行过程中可以产生多个同时存在.同时运行的线程.多进程机制可以合理利用资源,提高程序的运行效率.一个进程至少包含一个线程 ...

  4. GIL全局解释器锁+GIL全局解释器锁vs互斥锁+定时器+线程queue+进程池与线程池(同步与异步)

    以多线程为例写个互斥锁 from threading import Thread ,Lockimport timemutex = Lock() n = 100 def task(): global n ...

  5. C# 创建线程的简单方式:异步委托 .

    定义一个委托调用的方法:TakesAWhile //定义委托要引用的方法 private static int TakesAWhile(int data, int ms) { Console.Writ ...

  6. JavaScript:彻底理解同步、异步和事件循环(Event Loop) (转)

    原文出处:https://segmentfault.com/a/1190000004322358 一. 单线程 我们常说"JavaScript是单线程的". 所谓单线程,是指在JS ...

  7. JavaScript:彻底理解同步、异步和事件循环(Event Loop)

    一. 单线程 我们常说"JavaScript是单线程的". 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个.不妨叫它主线程. 但是实际上还存在其他 ...

  8. [转] JavaScript:彻底理解同步、异步和事件循环(Event Loop)

    一. 单线程 我们常说“JavaScript是单线程的”. 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个.不妨叫它主线程. 但是实际上还存在其他的线程.例如:处理A ...

  9. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  10. [多线程]线程基础(对象锁、class锁、同步、异步)

    synchronized.volatile.ReentrantLock.concurrent 线程安全:当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法) ...

随机推荐

  1. kubernetes的Service Account和secret

    系列目录 Service Account Service Account概念的引入是基于这样的使用场景:运行在pod里的进程需要调用Kubernetes API以及非Kubernetes API的其它 ...

  2. 40个国人iOS技术博客

    40个国人iOS技术博客 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 破船之家 http://beyondvincent.com/atom.xm ...

  3. Canvas学习笔记——缓动

    当你驾车在高速公路上行驶时,速度是很快的,而快到收费站时,则开始减速直到停下.将这个例子转换成物理模型就是当物体向终点运动时,开始速度会很快,而在快要到达终点时,速度会逐渐放缓直至0,整个运动过程就是 ...

  4. MVC准备工作

    准备工作 打开VS创建一个ASP.NET MVC空项目,在http://www.asp.net/mvc/overview/getting-started/introduction/getting-st ...

  5. eclipse代码注释模版

    设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是所有需设置注释的元 ...

  6. 主题:iframe高度的自适应

    在项目开发中,遇到的一个问题.弹出的页面中有iframe.例 <iframe src="www.baidu.html" width="100%" char ...

  7. iOS开发中的单元测试(三)——URLManager中的测试用例解析

    本文转载至 http://www.cocoachina.com/cms/plus/view.php?aid=8088   此前,我们在<iOS开发中的单元测试(一)&(二)>中介绍 ...

  8. Ubuntu上Eclipse安装PyDev方法和配置

    Ubuntu11.10中Eclipse安装PyDev插件方法 PyDev是Eclipse中用来开发python的一个插件,个人比较喜欢,下面介绍在Ubuntu下安装这个插件的方法.(在Windows下 ...

  9. 清除inline-block元素默认间距

    1. font-size:0; 2.letter-spaceing:-0.5em;

  10. emoji字符不能插入MySQL数据库,提示“'\xF0\x9F\x98\x84' for column 'XXXX' at row 1”

    从网络中取下的数据解析后不能插入数据库,提示某个字段有问题,问题提示如下: SQLException: Incorrect string value: '\xF0\x9F\x98\x84' for c ...