您的位置:首页 > 其它

等待异步委托的方式

2010-10-12 16:58 337 查看
等待异步委托的几种方式,觉得这个比较重要的,如是学习了下,把学习笔记记录如下

(一)代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//添加命名空间
using System.Threading;
using System.Diagnostics;

namespace 线程和同步
{
//创建线程方式:
//(一)异步委托创建线程
//   等待异步委托的方式:
//   (1)投票
//   (2)等待句柄
//   (3)异步回调
//(二)Thread类创建线程

class Program
{
public delegate int TakesAWhileDelegate(int data, int ms);
static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile started");
Thread.Sleep(ms);
Console.WriteLine("TakesAWhile completed");
return ++data;
}
static void Main(string[] args)
{
//Test1();
//Test2();
Test3();
Console.ReadKey();
}

//投票:是一种技术,检查委托是否完成了任务。
static void Test1()
{
TakesAWhileDelegate d1 = TakesAWhile;//定义异步委托实例
//Delegate类提供了方法BeginInvoke
//(1)BeginInvoke总含有AsyncCallBack和Object类型的额外参数,BeginInvoke(paramer1,paramer2,..,AsyncCallBack,Object)
//(2)返回类型为IAsyncResult.可获得的信息,并验证委托是否完成了任务(IsCompleted)
IAsyncResult ar = d1.BeginInvoke(1, 3000, null, null);
//只要委托没有完成其任务,程序的主线程就继续执行While循环。
while (!ar.IsCompleted)
{
//在主线程中做些其他的事情
Console.Write(".");
Thread.Sleep(50);
}
int result = d1.EndInvoke(ar);//EndInvoke()方法带回返回值。
Console.WriteLine("result:{0}",result);
//现象:
//可以看到主线程和委托线程同时运行,在委托线程执行完毕后,主线程就停止循环。
}

//等待句柄:使用IAsyncWaitHandle属性等待句柄,这个属性返回一个WaitHandle类型的对象
static void Test2()
{
TakesAWhileDelegate d1 = TakesAWhile;
IAsyncResult ar = d1.BeginInvoke(1, 3000, null, null);
while(true)
{
Console.Write(".");
//WaitHandle,它可以等待委托线程完成其任务
//WaitOne()将一个超时时间作为可选的第一个参数,在其中可以定义要等待的最大时间,这里设置为50毫秒,
//如果发生超时,WaiteOne()就返回false,While循环会继续执行,如果等待操作成功,就用一个中断退出while循环
if (ar.AsyncWaitHandle.WaitOne(50, false))
{
Console.WriteLine("Can get the result now");
break;
}
}
int result = d1.EndInvoke(ar);//EndInvoke()方法带回返回值。
Console.WriteLine("result:{0}", result);
}

//异步回调
//注意:使用回调方法,必须注意这个方法在线程中调用,而不是在主线程中调用
static void Test3()
{
TakesAWhileDelegate d1 = TakesAWhile;
//BeginInvoke总含有AsyncCallBack
//TakeAWhileCompleted赋予第三个参数以满足AsyncCallBack委托需求,对于最后一个参数可以传递任意对象,以便从回调方法中访问它
//这样回调方法就可以使用他获取异步方法的结果
//只要TakesAWhileDelegate,完成了其任务,就调用TakeAWhileCompleted方法,不需要在主线程中等待结果
//但是在委托线程饿任务未完成之前,不能停止主线程,除非刚刚停止的委托线程没有问题
d1.BeginInvoke(1, 3000,TakeAWhileCompleted ,d1);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}
}
//AsyncCallback委托定义了一个IAsyncResult的参数,其返回值是void
static void TakeAWhileCompleted(IAsyncResult ar)
{
if (ar == null) throw new ArgumentNullException("ar");
TakesAWhileDelegate d = ar.AsyncState as TakesAWhileDelegate;
Trace.Assert(d != null, "Invalid object type");
int result = d.EndInvoke(ar);//EndInvoke()方法带回返回值。
Console.WriteLine("result:{0}", result);

}

//异步回调(lamda表达式写法)
//运用场景:
//只有当代码不多,且实现代码不需要用于不同地方时,才应使用lamda表达式
static void Test4()
{
TakesAWhileDelegate d1 = TakesAWhile;
d1.BeginInvoke(1,3000,
ar=>//ar参数是IAsyncResult类型,在执行代码中,不需要把一个值赋给BeginInvoke()方法的最后一个参数,
//因为lamda表达式可以直接访问该方法的尾部的变量dl,但是lamda表达式仍是在委托线程中调用的
{
int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);

},
null);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}

}
}
}


运行截图:

(1)Test1运行截图



(2)Test2运行截图



(3)Test3运行截图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: