//创建一个控制台应用程序如下:
using System;
using System.Threading;
namespace ConsoleApplication1
{
public delegate string AsyncDelegate(int callDuration, out int threadId);
class Program
{
static void Main(string[] args)
{
//Fun1();
//Fun2();
//Fun3();
Fun4();
Console.ReadLine();
}
private static int threadId;
//阻塞等待 使用 EndInvoke 等待异步调用
static void Fun1()
{
//创建示例类的实例。
AsyncDemo ad = new AsyncDemo();
// 创建委托
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// 委托在这里开始异步调用。
IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
//人为的线程阻塞。
Thread.Sleep(0);
//Thread.CurrentThread.Name = "主线程";
Console.WriteLine("主线程 {0}开始工作",Thread.CurrentThread.ManagedThreadId);
// 委托开始EndInvoke调用,这个过程会使主线程等待异步调用完成并返回结果。
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("使用 EndInvoke 等待异步调用!!!");
Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
}
//阻塞等待 使用 WaitHandle 等待异步调用
static void Fun2()
{
AsyncDemo ad = new AsyncDemo();
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
//主线程在这里等待,直到异步线程执行完。
ar.AsyncWaitHandle.WaitOne();
// 和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前
//在这里做点任何你想作的事。
//调用EndInvoke获取异步调用的返回结果.
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("使用 WaitHandle 等待异步调用!!!");
Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
}
//轮询状态 轮询异步调用完成
static void Fun3()
{
AsyncDemo ad = new AsyncDemo();
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
Console.WriteLine("使用轮询异步调用!!!");
Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
//这里每隔10毫秒就检测(轮询)一下异步执行的状态,
//直到异步调用完成,IsCompleted的值变为ture为止。
int count = 0;
DateTime a = DateTime.Now;
while (ar.IsCompleted == false)
{
Thread.Sleep(10);
count++;
}
string dt = (DateTime.Now - a).ToString();
Console.WriteLine(count);
Console.WriteLine("程序耗时"+dt);
//还记得微软的那个善意的提醒吗?虽然IsCompleted为true了,
//我们还是调用一下EndInvoke,来获取返回值。
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
}
//通知机制 异步调用完成时执行回调方法
static void Fun4()
{
AsyncDemo ad = new AsyncDemo();
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
//注意第三个参数,这就是我们要用到的回调方法。
//第四个参数更为有趣,它可以是任何Object对象,这里它就是
//执行异步调用的委托本身,把委托本身传递进去的原因在下面可以看到。
Console.WriteLine("异步调用完成时执行回调!!!");
Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, new AsyncCallback(CallbackMethod), dlgt);
Console.WriteLine("主线程 {0}结束工作", Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
//回调函数必须严格的遵照AsyncCallback委托的签名。
static void CallbackMethod(IAsyncResult ar)
{
//在这里,上面那个dlgt作为参数的作用得到了体现,原来它就是为了完成对EndInvoke的调用啊。
AsyncDelegate dlgt = (AsyncDelegate)ar.AsyncState;
//通过对EndInvoke的调用获取返回值。
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
}
}
//使用异步编程模型
public class AsyncDemo
{
public string TestMethod(int callDuration, out int threadId)
{
Console.WriteLine("异步方法开始工作");
Thread.Sleep(callDuration);
//Thread.CurrentThread.Name = "异步线程";
threadId = Thread.CurrentThread.ManagedThreadId;
return "异步方法执行时间 " + callDuration.ToString();
}
}
}
上面的注释都很详细相信大家很容易看得懂。
为博主转载,忘记此demo的出处了,如若侵权,即可删除。