异步编程测试:四种模式.
using System;
namespace AsynTest
{
public class AsyncDemo {
public delegate string AsyncDelegate(int callDuration,out int threadId);
public string TestMethod(int callDuration,out int threadId) {
Console.WriteLine("Test method begins.");
System.Threading.Thread.Sleep(callDuration);
threadId=AppDomain.GetCurrentThreadId();
return "MyCallTime was "+callDuration.ToString();
}
}
class Class1
{
//使用EndInvoke等待导步调用
public static void test1() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用 WaitHandle 等待异步调用
public static void test2() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
//阻塞当前线程,以使异部线程开始执行,异部线程开始执行后,主线程就可以继续了.
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
//阻塞当前线程,直接收到信号为止
ar.AsyncWaitHandle.WaitOne();
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用 轮询 等待异步调用
public static void test3() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
//阻塞当前线程,以使异部线程开始执行,异部线程开始执行后,主线程就可以继续了.
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
while(!ar.IsCompleted) {
Console.WriteLine("Waiting");
System.Threading.Thread.Sleep(10);
}
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用回调
////使用回调方式不阻塞主线程,适合不需要等待异步调用结果的情况.
public static void test4() {
int threadId;
AsyncDemo ad = new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt = new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(3000,
out threadId,
new AsyncCallback(test4_forCallback),
dlgt );
Console.WriteLine("Press Enter to close application.");
Console.ReadLine();
}
public static void test4_forCallback(System.IAsyncResult ar) {
int threadId;
AsynTest.AsyncDemo.AsyncDelegate dlgt = (AsynTest.AsyncDemo.AsyncDelegate) ar.AsyncState;
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
[STAThread]
static void Main(string[] args)
{
test1();
test2();
test3();
test4();
}
}
}
namespace AsynTest
{
public class AsyncDemo {
public delegate string AsyncDelegate(int callDuration,out int threadId);
public string TestMethod(int callDuration,out int threadId) {
Console.WriteLine("Test method begins.");
System.Threading.Thread.Sleep(callDuration);
threadId=AppDomain.GetCurrentThreadId();
return "MyCallTime was "+callDuration.ToString();
}
}
class Class1
{
//使用EndInvoke等待导步调用
public static void test1() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用 WaitHandle 等待异步调用
public static void test2() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
//阻塞当前线程,以使异部线程开始执行,异部线程开始执行后,主线程就可以继续了.
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
//阻塞当前线程,直接收到信号为止
ar.AsyncWaitHandle.WaitOne();
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用 轮询 等待异步调用
public static void test3() {
int threadId;
AsyncDemo ad=new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt=new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar=dlgt.BeginInvoke(3000,out threadId,null,null);
//阻塞当前线程,以使异部线程开始执行,异部线程开始执行后,主线程就可以继续了.
System.Threading.Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",AppDomain.GetCurrentThreadId());
while(!ar.IsCompleted) {
Console.WriteLine("Waiting");
System.Threading.Thread.Sleep(10);
}
string ret=dlgt.EndInvoke(out threadId,ar);
Console.WriteLine("The call exceute on thread {0},with return value \"{1}\".",threadId,ret);
}
//使用回调
////使用回调方式不阻塞主线程,适合不需要等待异步调用结果的情况.
public static void test4() {
int threadId;
AsyncDemo ad = new AsyncDemo();
AsynTest.AsyncDemo.AsyncDelegate dlgt = new AsynTest.AsyncDemo.AsyncDelegate(ad.TestMethod);
IAsyncResult ar = dlgt.BeginInvoke(3000,
out threadId,
new AsyncCallback(test4_forCallback),
dlgt );
Console.WriteLine("Press Enter to close application.");
Console.ReadLine();
}
public static void test4_forCallback(System.IAsyncResult ar) {
int threadId;
AsynTest.AsyncDemo.AsyncDelegate dlgt = (AsynTest.AsyncDemo.AsyncDelegate) ar.AsyncState;
string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
[STAThread]
static void Main(string[] args)
{
test1();
test2();
test3();
test4();
}
}
}
一点说明:为什么在标题中要嵌入英文?原因是为了能够让国外的网友能查询到这篇文章。平常在Google上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。