异步委托的几种实现方式
最近,在看C#高级编程第七版的线程、任务、同步这一章,因为现在多线程编程,异步编程对构建响应灵敏的界面以及构建高可伸缩性的服务应用是多么重要。现在就来记录一下自己今天学习的成果。
创建线程的一种简单方式是定义一个委托,并异步调用它。总结一下,异步调用委托的方式有如下3种:
1.投票
//定义一个需要一定的时间才能执行完毕的方法
static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile started");
Thread.Sleep(ms);
Console.WriteLine("TakesAWhile completed");
return ++data;
}
//要从委托中调用这个方法,必须定义一个有相同参数和返回类型的委托
public delegate int TakesAWhileDelegate(int data,int ms);
//所创建的delegate类提供了BeginInvoke()方法,在该方法中,可以传递用委托定义的输入的函数。BeginInvoke()方法总是有AsyncCallback和object类型的两个额外参数。BeginInvoke()方法的返回类型是IAsyncResult。通过IAsyncResult,可以获得该委托的相关信息,并通过IsCompleted属性验证该委托是否完成了任务。只要委托没有完成其任务,程序的主线程就继续执行while循环。
static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
//使用投票方式调用异步委托
IAsyncResult ar = d1.BeginInvoke(1, 3000, null, null);
while (!ar.IsCompleted)
{
//doing something else in the main thread
Console.Write(".");
Thread.Sleep(50);
}
int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
}
2.等待句柄
static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
//使用等待句柄的方式调用异步委托
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);
}
}
3.使用异步回调
static void Main(string[] args)
{
TakesAWhileDelegate d1 = TakesAWhile;
d1.BeginInvoke(1, 3000, TakesAWhileCompleted, d1);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}
}
static void TakesAWhileCompleted(IAsyncResult ar)
{
if (ar == null) throw new ArgumentException("ar");
TakesAWhileDelegate d1 = ar.AsyncState as TakesAWhileDelegate;
Trace.Assert(d1 != null, "Invalid object type");
int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
}
//使用异步回调-lamda表达式的方式调用委托
static void Main(string[] args)
{
d1.BeginInvoke(1, 3000, ar =>
{
int result = d1.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
}, null);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}
}