创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。
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()方法的参数,也可以使用相同的方式获得结果。