我知道接下来要展示的内容是错误的,但我想知道到底发生了什么。由于我的声誉较低,我无法附加图片。
我有.NET 7 API 项目。
我在同步方法(API)中使用
Task.Delay()
:
using (var client = new HttpClient() { Timeout = System.TimeSpan.FromSeconds(15)})
{
var response = client.GetAsync("https://...");
var canProceed = false;
while (!canProceed)
{
if (response.IsCompleted)
{
canProceed = true;
}
Task.Delay(25);
};
}
我知道
Task.Delay()
不会拖延。
然后我使用一个单独的控制台应用程序并使用
Parallel.For
点击此 API - 10.000 次。使用 JetBrains dotMemory,我在内存消耗方面得到了可怕的结果。运行点击 Api 的控制台应用程序几秒钟后,API 应用程序的内存从 100mb 增长到 4GB。当我比较两个快照时 - “SurvivedBytes”显示 ConcurrentQueueTask.Delay(25);
不是并且等待不会阻塞循环,它只会启动所有底层基础设施,仅此而已,所以基本上您将不断调用 Task.Delay(25);
直到响应完成而无需任何等待/阻塞。因此资源消耗。
您当然可以使用
Task.Delay(25).GetAwaiter().GetResult();
来阻止它,但您确实不应该阻止异步代码。使用Thread.Sleep
。或者response.GetAwaiter().GetResult()
。
或者更好 - 让你的方法异步并等待客户端调用(API 方法可以是异步的,并且可以说在大多数情况下应该是异步的):
var response = await client.GetAsync("https://...");
IHttpClientFactory
而不是手动创建 HttpClient
。