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的时机。
参考
http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.html