这是我的环境:Win 7 上的 IIS7.5、.NET 4、App Pool Integrated
网络配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>
测试.aspx
<%@ Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
protected void OnAction(object sender, EventArgs e)
{
int count;
status.Text = (int.TryParse(status.Text, out count) ? count + 1 : 0).ToString();
Session["test"] = count;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>IIS Session Hang Test</title>
<script>
var mutiPostback = function () {
var e = document.getElementById('LinkButton1');
e.click();
e.click();
};
</script>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager runat="server" ID="SM">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="LinkButton1"/>
</Triggers>
<ContentTemplate>
<asp:Label runat="server" ID="status" />
</ContentTemplate>
</asp:UpdatePanel>
<input type="button" id="button1" onclick="mutiPostback();" value="MultiPostback"/>
<div style="display: none">
<asp:Button ID="LinkButton1" runat="server" OnClick="OnAction" Text="Click" />
</div>
</form>
</body>
</html>
是的,多次回发是故意的,我们注意到这种行为会导致许多请求卡在 RequestAcquireState 中,并最终阻止服务器接受任何新请求。但是,这个问题只能在 IE 下观察到,而在 Chrome 或 FF 上是看不到的。
要进行测试,请连续单击多次回发按钮。这将更新状态编号。然后,您将能够观察到在使用 IE 时该数字停止增加,表明请求卡住的问题。
我能够使用以下 IIS 和 IE 版本产生此问题:
测试的 IIS 版本
- 安装了 .Net 4.5 的 Windows Server 2008 R2 上的 7.5.7600.16385
- 安装了 .Net 4.5 的 Windows 7 Pro 上的 7.5.7600.16385
IE版本测试
- Windows 7 Pro 上的 9.0.8112.16421
- Windows Server 2008 R2 上的 8.0.7600.16385
- Windows Server 2003 SP2 上的 6.0.3790.3959
我观察到的异常情况是,当访问本地 IIS 时,Windows Server 2008 R2 上的 8.0.7600.16385 不会导致此阻塞问题。但是,如果我使用浏览器访问远程 IIS,则可以重现该问题。在 IE 9 上,无论 IIS 是在远程还是本地,我都可以重现该问题。
这是工作进程请求列表中挂起请求的屏幕截图。
现在我们找到了一些解决这个问题的方法,但在我们的情况下没有一个是可以接受的:
- 删除/注释掉会话使用情况。
- 将应用程序池更改为经典模式。
注意:我们还发现,即使我们不直接使用示例中的Session,问题仍然存在。IE:如果我们添加一个 Global.asax.cs 并添加一个空的 Session_Start 事件处理程序,请求仍然会在 RequestAcquireState 中挂起。
有谁知道为什么会发生这种情况,我们如何解决这个似乎只在集成托管管道模式下发生的问题?