谈多线程谈到现在,我们要明确多线程的一个好处是可以进行并行的运算(充分利用多核处理器,对 于桌面应用程序来说就更重要一点了,没有WEB服务器,利用多核只能靠自己),还有一个好处就是异步 操作,就是我们可以让某个长时间的操作独立运行,不妨碍主线程继续进行一些计算,然后异步的去返回 结果(也可以不返回)。前者能提高性能是因为能利用到多核,而后者能提高性能是因为能让CPU不在等 待中白白浪费,其实异步从广义上来说也可以理解为某种并行的运算。在之前的这么多例子中,我们大多 采用手工方式来新开线程,之前也说过了,在大并发的环境中随便开始和结束线程的代价太大,需要利用 线程池,使用线程池的话又觉得少了一些控制。现在让我们来总结一下大概会有哪几种常见的异步编程应 用模式:
1) 新开一个A线程执行一个任务,然后主线程执行另一个任务后等待线程返回结果后继续
2) 新开一个A线程执行一个任务,然后主线程不断轮询A线程是否执行完毕,如果没有的话可以选择 等待或是再进行一些操作
3) 新开一个A线程执行一个任务,执行完毕之后立即执行一个回调方法去更新一些状态变量,主线程 和A线程不一定有直接交互
4) 新开一个A线程执行一个任务,执行完毕之后啥都不做
(补充一句,异步编程不一定是依赖于线程的,从广义上来说,使用队列异步处理数据也可以算是一 种异步编程模式)
对于这任何一种,我们要使用线程池来编写应用的话都是比较麻烦的,比如如下的代码实现了1)这种 应用:
class AsyncObj
{
public EventWaitHandle AsyncWaitHandle { get; set; }
public object Result { get; set; }
public AsyncObj()
{
AsyncWaitHandle = new AutoResetEvent(false);
}
}
AsyncObj ao = new AsyncObj();
ThreadPool.QueueUserWorkItem(state =>
{
AsyncObj obj = state as AsyncObj;
Console.WriteLine("asyc operation started @ " + DateTime.Now.ToString ("mm:ss"));
Thread.Sleep(2000);
Console.WriteLine("asyc operation completed @ " + DateTime.Now.ToString ("mm:ss"));
obj.Result = 100;
obj.AsyncWaitHandle.Set();
}, ao);
Console.WriteLine("main operation started @ " + DateTime.Now.ToString("mm:ss"));
Thread.Sleep(1000);
Console.WriteLine("main operation completed @ " + DateTime.Now.ToString ("mm:ss"));
ao.AsyncWaitHandle.WaitOne();
Console.WriteLine("get syc operation result : " + ao.Result.ToString() + " @ " + DateTime.Now.ToString("mm:ss"));
结果如下: