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 | 支持 |
-
如ThreadPool.UnsafeQueueUserWorkItem(()=>result=Add(1,2));
-
用Task<>
-
里面在程序末尾EventWaitHandle.Set(),外面WaitOne(TimeSpan)。
-
获得BeginInvoke的返回值asyncResult,再调asyncResult.AsyncWaitHandle.WaitOne();
有图有真相。这是各种异步方法循环调用N次所需的时间。
代码如下:
static void Main(string[] args) { Action threadStart = (() => { }); WaitCallback waitCallback = new WaitCallback(a => { }); Stopwatch stopWatch = new Stopwatch(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < 10000; i++) { System.Threading.ThreadPool.UnsafeQueueUserWorkItem(waitCallback, null); } stopWatch.Stop(); Console.WriteLine("{0,-40}{1}", "ThreadPool.UnsafeQueueUserWorkItem():", stopWatch.ElapsedTicks); GC.Collect(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < 10000; i++) { System.Threading.ThreadPool.QueueUserWorkItem(waitCallback); } stopWatch.Stop(); Console.WriteLine("{0,-40}{1}", "ThreadPool.QueueUserWorkItem():", stopWatch.ElapsedTicks); GC.Collect(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < 10000; i++) { Task t = new Task(threadStart); t.Start(); } stopWatch.Stop(); Console.WriteLine("{0,-40}{1}", "Task():", stopWatch.ElapsedTicks); GC.Collect(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < 10000; i++) { threadStart.BeginInvoke(null, null); } stopWatch.Stop(); Console.WriteLine("{0,-40}{1}", "Delegate.BeinInvoke():", stopWatch.ElapsedTicks); }
注意,上面BeginInvoke的用法并不完整,应当再调用EndInvoke。但是鉴于BeginInvoke已经最慢了,EndInvoke便不加了。
所以,如果无需返回值,一般就用ThreadPool吧,要更多控制,就Task。鄙人想不到用BeginInvoke的时机。