使用.Net 进行 Pro Asynchrnous编程:
for (int nTry = 0; nTry < 3; nTry++) { try { AttemptOperation(); break; } catch (OperationFailedException) { } Thread.Sleep(2000); }
在休眠时,线程不消耗任何基于CPU的资源, 但线程存活的事实意味着它仍然在消耗 内存资源。在桌面应用程序上,这可能不大 处理,但在服务器应用程序上,有很多线程在休眠 不理想,因为如果更多的工作到达服务器,它可能必须 旋转更多线程,增加内存压力并增加额外的内存 操作系统要管理的资源。
理想情况下,您不希望将线程置于睡眠状态 简单地放弃,让线程可以自由地为其他人服务 要求。当您准备好再次继续使用CPU资源时 你可以获得一个线程(不一定是同一个)并继续 处理。您可以通过不将线程放入来解决此问题 睡觉,而是使用等待被认为完成的任务 在一定时期内。
for (int nTry = 0; nTry < 3; nTry++) { try { AttemptOperation(); break; } catch (OperationFailedException) { } await Task.Delay(2000); }
我不遵循作者的推理。虽然调用await Task.Delay
确实会释放这个线程(处理请求),但Task.Delay
创建的任务也会占用其他一些线程来运行。那么这段代码真的能让服务器处理更多的同步请求,或者文本错误了吗?!
答案 0 :(得分:9)
Task.Delay
不会占用其他一些帖子。它为您提供无阻塞的任务。它启动一个计时器,在其回调中完成该任务。等待时,计时器不使用任何线程。
像延迟或IO这样的异步操作只是将工作推送到另一个线程,这是一个常见的神话。他们不。它们使用OS工具在操作正在进行时真正使用零线程。 (他们显然需要使用一些线程来启动和完成操作。)
如果异步只是将工作推送到另一个线程,那么它几乎是无用的。它的价值只是让UI在客户端应用程序中保持响应。在服务器上它只会造成伤害。事实并非如此。
async IO的值是减少内存usag(减少线程堆栈),上下文切换和线程池利用率。
您发布的代码的异步版本将扩展到数万个并发请求(如果您适当地增加ASP.NET限制,这是一个简单的web.config更改),内存使用量很少。