IHttpAsyncHandler的线程

时间:2014-08-05 14:29:24

标签: c# multithreading asynchronous ihttpasynchandler

我阅读了this article并了解了有关IHttpAsyncHandler的信息。

根据下图,我调用AsyncHandler时会创建2个线程。

当一个请求到来时,IIS将获取一个线程 - 线程1来处理这个请求,当它调用beginXXX方法时,线程2将被创建并处理这个真实的逻辑。

我的问题是:

当线程2运行时,连接仍然存在,等待响应。

当线程2运行时,线程1的状态是什么?它在睡觉吗?或者它被释放?

如果线程1正在休眠,当线程2完成时,线程1被唤醒并发送响应??

如果线程1被释放,当线程2完成时,是否有一个新线程被创建为线程1?这个新的线程1将响应发送给客户端。

线程1和线程2在同一个线程池中,不是吗? 如果是这样,可用的线程数是平衡的,这样做的目的是什么?

enter image description here

1 个答案:

答案 0 :(得分:2)

您没有将线程池视为池。当"线程1"完成其在PreRender的工作后,它将返回池中以便出于任何目的重复使用。数据准备好后End将从线程池中选择一个随机线程并完成其工作并在其上发送响应。该随机线程可以是一个新线程,也可以是与之前返回池中的工作相同的线程。

这一点在BeginEnd之间的窗口中,该线程被重新调整到池中,并且可以为其他连接提供服务。这使您可以拥有比系统可以处理的并发线程更多的并发连接,在同步版本中,一旦达到最大并发线程数,就无法再处理新请求。


让我进一步了解正在发生的事情

这是两个同步连接请求显示为基线的时间线,为简单起见,我们将说每个步骤需要1ms才能执行,PreRender除外,需要19ms才能完成。

╔═══════╦════════════════════════╦══════════════════╦═════════════════╦═══════════════════╗
║ Time  ║ Action (Connection #)  ║ Open Connections ║ Running Threads ║ Available Threads ║
╠═══════╬════════════════════════╬══════════════════╬═════════════════╬═══════════════════╣
║  0 ms ║ Connection Request (1) ║                0 ║               0 ║                 2 ║
║  1 ms ║ PreInit  (1)           ║                1 ║               1 ║                 1 ║
║  2 ms ║ Init  (1)              ║                1 ║               1 ║                 1 ║
║  3 ms ║ InitComplete  (1)      ║                1 ║               1 ║                 1 ║
║  4 ms ║ PreLoad  (1)           ║                1 ║               1 ║                 1 ║
║  5 ms ║ LoadComplete  (1)      ║                1 ║               1 ║                 1 ║
║  6 ms ║ PreRender  (1)         ║                1 ║               1 ║                 1 ║
║ 10 ms ║ Connection Request (2) ║                1 ║               1 ║                 1 ║
║ 11 ms ║ PreInit  (2)           ║                2 ║               2 ║                 0 ║
║ 12 ms ║ Init  (2)              ║                2 ║               2 ║                 0 ║
║ 13 ms ║ InitComplete  (2)      ║                2 ║               2 ║                 0 ║
║ 14 ms ║ PreLoad  (2)           ║                2 ║               2 ║                 0 ║
║ 15 ms ║ LoadComplete  (2)      ║                2 ║               2 ║                 0 ║
║ 16 ms ║ PreRender  (2)         ║                2 ║               2 ║                 0 ║
║ 25 ms ║ PreRenderComplete  (1) ║                2 ║               2 ║                 0 ║
║ 26 ms ║ SaveState  (1)         ║                2 ║               2 ║                 0 ║
║ 27 ms ║ SaveStateComplete  (1) ║                2 ║               2 ║                 0 ║
║ 28 ms ║ Render  (1)            ║                2 ║               2 ║                 0 ║
║ 29 ms ║ Send Response  (1)     ║                1 ║               1 ║                 1 ║
║ 35 ms ║ PreRenderComplete  (2) ║                1 ║               1 ║                 1 ║
║ 36 ms ║ SaveState  (2)         ║                1 ║               1 ║                 1 ║
║ 37 ms ║ SaveStateComplete  (2) ║                1 ║               1 ║                 1 ║
║ 38 ms ║ Render  (2)            ║                1 ║               1 ║                 1 ║
║ 39 ms ║ Send Response  (2)     ║                0 ║               0 ║                 2 ║
╚═══════╩════════════════════════╩══════════════════╩═════════════════╩═══════════════════╝

以下是异步版本的时间表。

╔═══════╦════════════════════════╦══════════════════╦═════════════════╦═══════════════════╗
║ Time  ║ Action (Connection #)  ║ Open Connections ║ Running Threads ║ Available Threads ║
╠═══════╬════════════════════════╬══════════════════╬═════════════════╬═══════════════════╣
║  0 ms ║ Connection Request (1) ║                0 ║               0 ║                 2 ║
║  1 ms ║ PreInit  (1)           ║                1 ║               1 ║                 1 ║
║  2 ms ║ Init  (1)              ║                1 ║               1 ║                 1 ║
║  3 ms ║ InitComplete  (1)      ║                1 ║               1 ║                 1 ║
║  4 ms ║ PreLoad  (1)           ║                1 ║               1 ║                 1 ║
║  5 ms ║ LoadComplete  (1)      ║                1 ║               1 ║                 1 ║
║  6 ms ║ PreRender  (1)         ║                1 ║               1 ║                 1 ║
║  7 ms ║ Begin (1)              ║                1 ║               0 ║                 2 ║
║ 10 ms ║ Connection Request (2) ║                1 ║               0 ║                 2 ║
║ 11 ms ║ PreInit  (2)           ║                2 ║               1 ║                 1 ║
║ 12 ms ║ Init  (2)              ║                2 ║               1 ║                 1 ║
║ 13 ms ║ InitComplete  (2)      ║                2 ║               1 ║                 1 ║
║ 14 ms ║ PreLoad  (2)           ║                2 ║               1 ║                 1 ║
║ 15 ms ║ LoadComplete  (2)      ║                2 ║               1 ║                 1 ║
║ 16 ms ║ PreRender  (2)         ║                2 ║               1 ║                 1 ║
║ 17 ms ║ Begin (2)              ║                2 ║               0 ║                 2 ║
║ 25 ms ║ End (1)                ║                2 ║               1 ║                 1 ║
║ 26 ms ║ PreRenderComplete  (1) ║                2 ║               1 ║                 1 ║
║ 27 ms ║ SaveState  (1)         ║                2 ║               1 ║                 1 ║
║ 28 ms ║ SaveStateComplete  (1) ║                2 ║               1 ║                 1 ║
║ 29 ms ║ Render  (1)            ║                2 ║               1 ║                 1 ║
║ 30 ms ║ Send Response  (1)     ║                1 ║               0 ║                 2 ║
║ 35 ms ║ End (2)                ║                1 ║               1 ║                 1 ║
║ 36 ms ║ PreRenderComplete  (2) ║                1 ║               1 ║                 1 ║
║ 37 ms ║ SaveState  (2)         ║                1 ║               1 ║                 1 ║
║ 38 ms ║ SaveStateComplete  (2) ║                1 ║               1 ║                 1 ║
║ 39 ms ║ Render  (2)            ║                1 ║               1 ║                 1 ║
║ 40 ms ║ Send Response  (2)     ║                0 ║               0 ║                 2 ║
╚═══════╩════════════════════════╩══════════════════╩═════════════════╩═══════════════════╝

现在处理两个或更少的连接时,异步没有真正的好处,实际上由于额外的开销,它甚至可能会稍微慢一些。

但是看看当我们有超过2个并发连接时会发生什么。

同步:

╔═══════╦════════════════════════╦══════════════════╦═════════════════╦═══════════════════╗
║ Time  ║ Action (Connection #)  ║ Open Connections ║ Running Threads ║ Available Threads ║
╠═══════╬════════════════════════╬══════════════════╬═════════════════╬═══════════════════╣
║  0 ms ║ Connection Request (1) ║                0 ║               0 ║                 2 ║
║  1 ms ║ PreInit  (1)           ║                1 ║               1 ║                 1 ║
║  2 ms ║ Init  (1)              ║                1 ║               1 ║                 1 ║
║  3 ms ║ InitComplete  (1)      ║                1 ║               1 ║                 1 ║
║  4 ms ║ PreLoad  (1)           ║                1 ║               1 ║                 1 ║
║  5 ms ║ LoadComplete  (1)      ║                1 ║               1 ║                 1 ║
║  6 ms ║ PreRender  (1)         ║                1 ║               1 ║                 1 ║
║ 10 ms ║ Connection Request (2) ║                1 ║               1 ║                 1 ║
║ 11 ms ║ PreInit  (2)           ║                2 ║               2 ║                 0 ║
║ 12 ms ║ Init  (2)              ║                2 ║               2 ║                 0 ║
║ 13 ms ║ InitComplete  (2)      ║                2 ║               2 ║                 0 ║
║ 14 ms ║ PreLoad  (2)           ║                2 ║               2 ║                 0 ║
║ 15 ms ║ LoadComplete  (2)      ║                2 ║               2 ║                 0 ║
║ 16 ms ║ PreRender  (2)         ║                2 ║               2 ║                 0 ║
║ 20 ms ║ Connection Request (3) ║                2 ║               2 ║                 0 ║
║ 25 ms ║ PreRenderComplete  (1) ║                2 ║               2 ║                 0 ║
║ 26 ms ║ SaveState  (1)         ║                2 ║               2 ║                 0 ║
║ 27 ms ║ SaveStateComplete  (1) ║                2 ║               2 ║                 0 ║
║ 28 ms ║ Render  (1)            ║                2 ║               2 ║                 0 ║
║ 29 ms ║ Send Response  (1)     ║                1 ║               1 ║                 1 ║
║ 30 ms ║ PreInit  (3)           ║                2 ║               2 ║                 0 ║
║ 31 ms ║ Init  (3)              ║                2 ║               2 ║                 0 ║
║ 32 ms ║ InitComplete  (3)      ║                2 ║               2 ║                 0 ║
║ 33 ms ║ PreLoad  (3)           ║                2 ║               2 ║                 0 ║
║ 34 ms ║ LoadComplete  (3)      ║                2 ║               2 ║                 0 ║
║ 35 ms ║ PreRender  (3)         ║                2 ║               2 ║                 0 ║
║ 35 ms ║ PreRenderComplete  (2) ║                2 ║               2 ║                 0 ║
║ 36 ms ║ SaveState  (2)         ║                2 ║               2 ║                 0 ║
║ 37 ms ║ SaveStateComplete  (2) ║                2 ║               2 ║                 0 ║
║ 38 ms ║ Render  (2)            ║                2 ║               2 ║                 0 ║
║ 39 ms ║ Send Response  (2)     ║                1 ║               1 ║                 1 ║
║ 54 ms ║ PreRenderComplete  (3) ║                1 ║               1 ║                 1 ║
║ 55 ms ║ SaveState  (3)         ║                1 ║               1 ║                 1 ║
║ 56 ms ║ SaveStateComplete  (3) ║                1 ║               1 ║                 1 ║
║ 57 ms ║ Render  (3)            ║                1 ║               1 ║                 1 ║
║ 58 ms ║ Send Response  (3)     ║                0 ║               0 ║                 2 ║
╚═══════╩════════════════════════╩══════════════════╩═════════════════╩═══════════════════╝

异步:

╔═══════╦════════════════════════╦══════════════════╦═════════════════╦═══════════════════╗
║ Time  ║ Action (Connection #)  ║ Open Connections ║ Running Threads ║ Available Threads ║
╠═══════╬════════════════════════╬══════════════════╬═════════════════╬═══════════════════╣
║  0 ms ║ Connection Request (1) ║                0 ║               0 ║                 2 ║
║  1 ms ║ PreInit  (1)           ║                1 ║               1 ║                 1 ║
║  2 ms ║ Init  (1)              ║                1 ║               1 ║                 1 ║
║  3 ms ║ InitComplete  (1)      ║                1 ║               1 ║                 1 ║
║  4 ms ║ PreLoad  (1)           ║                1 ║               1 ║                 1 ║
║  5 ms ║ LoadComplete  (1)      ║                1 ║               1 ║                 1 ║
║  6 ms ║ PreRender  (1)         ║                1 ║               1 ║                 1 ║
║  7 ms ║ Begin (1)              ║                1 ║               0 ║                 2 ║
║ 10 ms ║ Connection Request (2) ║                1 ║               0 ║                 2 ║
║ 11 ms ║ PreInit  (2)           ║                2 ║               1 ║                 1 ║
║ 12 ms ║ Init  (2)              ║                2 ║               1 ║                 1 ║
║ 13 ms ║ InitComplete  (2)      ║                2 ║               1 ║                 1 ║
║ 14 ms ║ PreLoad  (2)           ║                2 ║               1 ║                 1 ║
║ 15 ms ║ LoadComplete  (2)      ║                2 ║               1 ║                 1 ║
║ 16 ms ║ PreRender  (2)         ║                2 ║               1 ║                 1 ║
║ 17 ms ║ Begin (2)              ║                2 ║               0 ║                 2 ║
║ 20 ms ║ Connection Request (3) ║                3 ║               0 ║                 2 ║
║ 21 ms ║ PreInit  (3)           ║                3 ║               1 ║                 1 ║
║ 22 ms ║ Init  (3)              ║                3 ║               1 ║                 1 ║
║ 23 ms ║ InitComplete  (3)      ║                3 ║               1 ║                 1 ║
║ 24 ms ║ PreLoad  (3)           ║                3 ║               1 ║                 1 ║
║ 25 ms ║ End (1)                ║                3 ║               2 ║                 0 ║
║ 25 ms ║ LoadComplete  (3)      ║                3 ║               2 ║                 0 ║
║ 26 ms ║ PreRenderComplete  (1) ║                3 ║               2 ║                 0 ║
║ 26 ms ║ PreRender  (3)         ║                3 ║               2 ║                 0 ║
║ 27 ms ║ SaveState  (1)         ║                3 ║               2 ║                 0 ║
║ 27 ms ║ Begin (3)              ║                3 ║               1 ║                 0 ║
║ 28 ms ║ SaveStateComplete  (1) ║                3 ║               1 ║                 1 ║
║ 29 ms ║ Render  (1)            ║                3 ║               1 ║                 1 ║
║ 30 ms ║ Send Response  (1)     ║                2 ║               0 ║                 2 ║
║ 35 ms ║ End (2)                ║                2 ║               1 ║                 1 ║
║ 36 ms ║ PreRenderComplete  (2) ║                2 ║               1 ║                 1 ║
║ 37 ms ║ SaveState  (2)         ║                2 ║               1 ║                 1 ║
║ 38 ms ║ SaveStateComplete  (2) ║                2 ║               1 ║                 1 ║
║ 39 ms ║ Render  (2)            ║                2 ║               1 ║                 1 ║
║ 40 ms ║ Send Response  (2)     ║                1 ║               0 ║                 2 ║
║ 45 ms ║ End (3)                ║                1 ║               1 ║                 1 ║
║ 46 ms ║ PreRenderComplete  (3) ║                1 ║               1 ║                 1 ║
║ 47 ms ║ SaveState  (3)         ║                1 ║               1 ║                 1 ║
║ 48 ms ║ SaveStateComplete  (3) ║                1 ║               1 ║                 1 ║
║ 49 ms ║ Render  (3)            ║                1 ║               1 ║                 1 ║
║ 50 ms ║ Send Response  (3)     ║                0 ║               0 ║                 2 ║
╚═══════╩════════════════════════╩══════════════════╩═════════════════╩═══════════════════╝

请注意,在同步版本中,连接3在20ms时进入,但是当线程可用于处理请求时,它必须等到30ms。相比之下,异步版本在等待PreRender完成时将线程返回到池中,因此连接3立即能够开始处理。

因此,使用async不会增加每秒事务数,实际上它可能会略微降低每秒事务数。然而,它所做的是增加你的" Max Concurrent Transaction"计算并增加总吞吐量。