异步方法如何使用堆栈?

use*_*797 3 .net c# asp.net async-await

我刚刚开始使用.NET异步编程,每个人都说它对服务器端代码更好,因为如果我使用异步keywork,ASP.NET将不会为每个请求创建线程,并将为所有异步代码重用相同的线程.

因为每个线程都需要堆栈,并且可能有数百个线程,所以它有机会节省大量内存,例如:

regular: 1500 threads x 2mb = 3000 mb
async:   20 threads x 2mb   =   40 mb
Run Code Online (Sandbox Code Playgroud)

但它是否意味着异步代码在没有堆栈的情况下执行?或者它存储在哪里以及.NET如何使用它?

SLa*_*aks 8

您创建的每个线程都会分配一个完整的堆栈,无论您在该线程上使用多少.
因此,创建更少的线程将节省内存.

当异步方法等待操作完成时,它会将其状态保存在GC管理的堆上的编译器生成的对象(如lambda表达式的闭包)中.


Eri*_*ert 5

想想堆栈的用途:

1)执行个别陈述和表达时所需的临时空间.当你说"a = b + c + d"时,"b + c"的结果必须存储在某个地方才能加到d中.

2)存储其寿命已知等于或小于当前方法激活的其他变量.

3)激活当前方法后要运行的代码.

异步方法仅对第一个使用堆栈.(在某些情况下,甚至可能必须将其中一些临时值移到堆上.)由于异步方法的变量可能比当前方法的激活持续时间更长,因此必须将它们移动到堆上.异步方法的重点在于它将其延续存储在其他地方,它不使用堆栈作为延续的具体化.

因此,异步方法很少使用堆栈.相反,它们使用堆内存来存储它们的激活和延续信息.