在一次关于消息传递架构的网络研讨会上,演讲者提到了同步和长http/web请求的一些问题,GC一直在等待响应对象,并最终将它们转移到GC的第2代。
我很好奇异步等待调用是否也会发生同样的情况,因为它与CPU线程无关,更多的是内存泄漏。
static async Task Main(string[] args)
{
string response = await LongHTTPRequest();
Console.WriteLine(response);
}
public static async Task<string> LongHTTPRequest()
{
await Task.Delay(12000);
return await Task.FromResult("Response from RPC");
}
WebServers和Multitasking是一个奇怪的组合:
-
一方面,它大量使用隐式多线程。普通的ASP.NET服务器有一个线程池,每个CPU核心有几十到几百个线程。然后另一个相同大小的ThreadPool(但很少使用(。在请求级别上,它是一个复杂的并行单元。
-
另一方面,如果可以的话,您确实应该避免在服务器端执行显式多任务。整个设计是为了满足以下要求:
收到- 已处理
- 已发送结果
- 尽快从内存中删除,以免占用资源过长
如果你看看ASP页面的页面生命周期,你可以看到它。但它基本上适用于所有的网页开发。以及Web服务。以及数据库。
显式多任务处理可以是:
- 将请求保存在内存中的时间太长,导致资源不足(包括内存,但我更担心像这里的DB连接这样的非人化的东西(
- 没有及时返回响应,被丢弃,从而浪费了CPU时间和内存
如果你要用网页执行多任务,请在客户端执行。通常涉及一些AJAX或类似的,它查询一个单独的WebService。这让你可以同时处理多项任务,而不会有资源匮乏的风险。
带有图像的普通网页已经是一个例子。我们完全可以将图片与页面的其他部分一起内联发送。我们从一开始就知道如何做到这一点。但我们很少这样做。服务器发送一个纯HTML页面,没有内联图像,但有很多图像URL。然后浏览器(客户端(将异步下载每一个图像、CSS文件和JavaScript代码片段(后两者更有可能嵌入,但也不能保证(。一次一个单独的请求。