可以在异步回调中进行繁重的处理吗?

时间:2011-01-11 03:20:06

标签: .net asynchronous iasyncresult

可以在.NET的异步回调中进行大量处理,在返回之前将它们占用多秒钟吗?或者我是否剥夺了操作系统/重要资源的运行时间?

例如,考虑TcpListener.BeginAcceptSocket。我的回调开始于调用EndAcceptSocket,然后花费一段时间接收数据,然后才关闭套接字并返回。这是用于它的方式,还是我希望在我自己的线程上进行额外的处理?

2 个答案:

答案 0 :(得分:1)

是的,这是异步套接字(Tcp客户端,监听器等)的设计使用方式。您应始终确保调用end aysnc方法,然后执行所需的任何处理。不调用EndAccept(),EndSEnd(),EndReceive()等等方法可能会导致内存泄漏,因此遵循这个方法总是很好。

使用的线程与您自己手动假脱机后台线程没有什么不同,并且实际上被设计用于甚至几秒钟的“长期操作”。相信我,你不希望在调度或GUI线程上运行那么长时间。

我有超过90个基于移动的系统,它们使用异步套接字进行服务器的通信,它做得非常好:比Web服务快得多(记住所有的Web协议都在Socket上运行),易于检测错误,等等。

我在我的服务器代码上做了同样的事情(与其他一些WCF混合用于中间件和后端通信部件),这是我们使用过的最具规模的通信。你必须在谷歌上做一个谷歌,但有一个人使用这项技术发布他的测试,他能够支持1,000个并发通信到一个只有11个线程的服务器。还不错。

MS的服务器示例:http://msdn.microsoft.com/en-us/library/fx6588te.aspx

来自MS的客户端示例:http://msdn.microsoft.com/en-us/library/bew39x2a.aspx

要让它“完美”需要更多时间,但这是一个很好的起点。

答案 1 :(得分:1)

我重复了CodeProject article on this topic的实验,发现.NET 4的结果与2003年描述的类似。请注意,文章实际上没有列出有问题的部分的结果,但据我了解它的主要问题仍然存在。

我重复使用CodeProject文章中的代码 - 只需下载它以自行运行此测试或进行实验。

测试将尝试使用10个并行线程在1秒内尽可能高的数量。

使用10个后台主题(即new Thread()

T0 = 4451756
T1 = 4215159
T2 = 5449189
T3 = 6244135
T4 = 3297895
T5 = 5302370
T6 = 5256763
T7 = 3779166
T8 = 6309599
T9 = 6236041
Total = 50542073

使用10个ThreadPool工作项

T0 = 23335890
T1 = 20998989
T2 = 22920781
T3 = 9802624
T4 = 0
T5 = 0
T6 = 0
T7 = 0
T8 = 0
T9 = 0
Total = 77058284

请注意,在1秒的时间片中,只有4个线程池工作项实际执行过!这是在四核CPU上,因此每个核心有一个线程。在前四个完成后执行的其他任务因为分配的1秒已经过期,他们没有增加他们的计数器。

这里的结论:有长任务,ThreadPool会让一些任务等待其他任务!因此,我强烈建议不要在ThreadPool任务中进行任何长处理(例如异步完成处理程序)。否则,如果您的数据处理占用CPU,您可能会保留更多重要的异步调用,或者如果只有一些任务进行大量处理,您可能会有非常不稳定的性能。

使用文章

中的自定义ThreadPool实现
T0 = 7175934
T1 = 6983639
T2 = 5306292
T3 = 5078502
T4 = 3279956
T5 = 8116320
T6 = 3262403
T7 = 7678457
T8 = 8946761
T9 = 8500619
Total = 64328883