先在控制台中测试异步调用

首先声明一个具有int 和 out int 参数的委托AsyncDelegate,返回值为string

再声明一个threadId用来显示线程的ID

public delegate string AsyncDelegate(int callDuration, out int threadId);
private static int threadId;

 

 

在类AsyncDemo中建立异步方法

代码
public string TestMethod(int callDuration, out int threadId)
{
Console.WriteLine(
"异步方法开始执行");
for (int i = 0; i < 7; i++)
{
Thread.Sleep(callDuration);
Console.WriteLine(
"异步方法" + i);
}
threadId
= Thread.CurrentThread.ManagedThreadId;
Console.WriteLine(threadId);
Console.WriteLine(
"异步结束");
return "MyCallTime was " + callDuration.ToString();
}

异步方法在控制台上打印for循环,并且在for循环结束时打印当前线程的ID,最后返回string类型字符串。

 

在Main方法中创建一个测试类的实例,接着创建异步委托,然后使用BeginInvoke方法启动异步调用。其中包括两个异步委托的参数、一个AsyncCallback委托的回调方法还有一个object类型的参数(dlgt)。在异步委托中加入了异步所要调用的方法。

代码
static void Main(string[] args)
{
// 创建一个测试类的实例
AsyncDemo ad = new AsyncDemo();

// 创建委托
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);

// 启动异步调用. 包括一个 AsyncCallback委托的回调方法,
// 并且需要调用EndInvoke方法
//前两个参数为异步方法的参数
IAsyncResult ar = dlgt.BeginInvoke(1000,
out threadId,
new AsyncCallback(CallbackMethod),
dlgt);
//①dlgt.EndInvoke(out threadId, ar); 将优先执行异步方法在执行主方法
Console.WriteLine("主方法所在线程"+Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 4; i++)
{
Thread.Sleep(
1000);
Console.WriteLine(
"主线程" + i);
}
Console.WriteLine(
"主方法结束");
//②dlgt.EndInvoke(out threadId, ar); 在此处添加没有效果
Console.ReadLine();
}

其中在①处如果使用EndInvoke方法,主线程将被阻塞,直到异步调用完成在继续执行主线程的打印。如果在②处使用则与没有加是同样的效果。

由此可见,当异步开始时主线程将按照顺序运行下去,一直遇到EndInvoke将主线程阻塞为止。

 

回调方法

代码
static void CallbackMethod(IAsyncResult ar)
{
// 取回委托.
AsyncDelegate dlgt = (AsyncDelegate)ar.AsyncState;

// 调用EndInvoke取回结果.
string ret = dlgt.EndInvoke(out threadId, ar);
//string ret = ar.ToString();

Console.WriteLine(
"调用在线程{0}上执行, 返回值 \"{1}\".", threadId, ret);
}

回调方法是在异步方法结束时调用的,可以用来处理一些后续的操作。此处是打印回调方法所在的线程ID以及异步方法的返回值。

运行结果: