BeginInvoke、ThreadPool、Task三类异步方法的区别和速度比较

  速度(最快为1) 返回值 多参数 等待在时限内完成 超时后结束
ThreadPool.UnsafeQueueUserWorkItem() 1 非原生支持1 非原生支持 非原生支持3 不支持
ThreadPool.QueueUserWorkItem() 2.7 非原生支持1 非原生支持 非原生支持3 不支持
Task() 4.5 支持2 非原生支持 支持 自愿结束
Delegate.BeinInvoke() 25.4 非原生支持1 支持 支持4 不支持
Thread.Start() 11009 非原生支持1 非原生支持 非原生支持3 支持
  1. ThreadPool.UnsafeQueueUserWorkItem(()=>result=Add(1,2));

  2. Task<>

  3. 里面在程序末尾EventWaitHandle.Set(),外面WaitOne(TimeSpan)。

  4. 获得BeginInvoke的返回值asyncResult,再调asyncResult.AsyncWaitHandle.WaitOne();


 

有图有真相。这是各种异步方法循环调用N次所需的时间。

代码如下

 

[csharp] view plaincopy
 
  1. static void Main(string[] args)  
  2.    {  
  3.        Action threadStart = (() => { });  
  4.        WaitCallback waitCallback = new WaitCallback(a => { });  
  5.        Stopwatch stopWatch = new Stopwatch();  
  6.   
  7.        stopWatch.Reset();  
  8.        stopWatch.Start();  
  9.        for (int i = 0; i < 10000; i++)  
  10.        {  
  11.            System.Threading.ThreadPool.UnsafeQueueUserWorkItem(waitCallback, null);  
  12.        }  
  13.        stopWatch.Stop();  
  14.        Console.WriteLine("{0,-40}{1}", "ThreadPool.UnsafeQueueUserWorkItem():", stopWatch.ElapsedTicks);  
  15.        GC.Collect();  
  16.   
  17.        stopWatch.Reset();  
  18.        stopWatch.Start();  
  19.        for (int i = 0; i < 10000; i++)  
  20.        {  
  21.            System.Threading.ThreadPool.QueueUserWorkItem(waitCallback);  
  22.        }  
  23.        stopWatch.Stop();  
  24.        Console.WriteLine("{0,-40}{1}", "ThreadPool.QueueUserWorkItem():", stopWatch.ElapsedTicks);  
  25.        GC.Collect();  
  26.   
  27.        stopWatch.Reset();  
  28.        stopWatch.Start();  
  29.        for (int i = 0; i < 10000; i++)  
  30.        {  
  31.            Task t = new Task(threadStart);  
  32.            t.Start();  
  33.        }  
  34.        stopWatch.Stop();  
  35.        Console.WriteLine("{0,-40}{1}", "Task():", stopWatch.ElapsedTicks);  
  36.        GC.Collect();  
  37.   
  38.        stopWatch.Reset();  
  39.        stopWatch.Start();  
  40.        for (int i = 0; i < 10000; i++)  
  41.        {  
  42.            threadStart.BeginInvoke(null, null);  
  43.        }  
  44.        stopWatch.Stop();  
  45.        Console.WriteLine("{0,-40}{1}", "Delegate.BeinInvoke():", stopWatch.ElapsedTicks);  
  46.   
  47.    }   

 

注意,上面BeginInvoke的用法并不完整,应当再调用EndInvoke。但是鉴于BeginInvoke已经最慢了,EndInvoke便不加了。

所以,如果无需返回值,一般就用ThreadPool吧,要更多控制,就Task。鄙人想不到用BeginInvoke的时机。

 

参考

http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.html

posted on 2015-12-25 17:10  扶强  阅读(390)  评论(0编辑  收藏  举报