创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。
Delegate还支持异步地调用方法。在后台Delegate类会创建一个执行任务的线程。
为了说明委托的异步特性,从一个需要一定的时间才能执行完毕的方法开始。 TakesAWhile方法至少需要经过第2个变量传递的毫秒数才能执行完,因 为它调用了Thread.Sleep()方法。
static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile,start");
Thread.Sleep(ms);
Console.WriteLine("
TakesAWhile 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("
Can 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("
TakesAWhile 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()方法的参数,也可以使用相同的方式获得结果。
