为什么/什么时候会话写入容易受到线程终止的影响?

发布于 2024-08-21 04:14:26 字数 1189 浏览 8 评论 0原文

代码:

Session["foo"] = "bar";  
Response.Redirect("foo.aspx");

问题:

当 foo.aspx 从会话中读取“foo”时,它不在那里。 会话在那里,但“foo”没有任何价值。

我在我们的生产环境中间歇性地观察到了这一点。但我并不是想在这里问有关的问题Response.Redirect()

说明:

Bertrand Le Roy 解释道(粗体是我的):

现在,Redirect 所做的就是发送一个 给客户端的特殊标头,以便 它向服务器请求不同的 页面比它正在等待的页面要多。 服务器端,发送此消息后 header,重定向结束响应。 这是一件非常暴力的事情。 Response.End 实际上停止了 无论页面在何处执行 使用 ThreadAbortException。什么 真正发生在这里的是 会话令牌在战斗中丢失

我的结论是 Response.Redirect() 可能会很严厉地结束线程。如果它们发生得太接近那种高压的话,这可能会威胁到我的会议所写的内容。

问题:

ASP.NET 会话管理为何如此容易受到此攻击?在会话写入行“完成”之前,Response.Redirect() 代码行不会开始执行——它怎么会对我的会话写入造成如此大的威胁?

会话写入在下一行代码执行之前没有“完成”怎么办?是否存在其他场景,会话写入同样丢失(就好像它们从未发生过一样)?

THE CODE:

Session["foo"] = "bar";  
Response.Redirect("foo.aspx");

THE PROBLEM:

When foo.aspx reads "foo" from the session, it's not there. The session is there, but there's no value for "foo".

I've observed this intermittently in our production environment. But I don't mean here to ask a question about Response.Redirect().

THE EXPLANATION:

Bertrand Le Roy explains (the bolding is mine):

Now, what Redirect does is to send a
special header to the client so that
it asks the server for a different
page than the one it was waiting for.
Server-side, after sending this
header, Redirect ends the response.
This is a very violent thing to do.
Response.End actually stops the
execution of the page wherever it is
using a ThreadAbortException. What
happens really here is that the
session token gets lost in the battle.

My takeaway there is that Response.Redirect() can be heavy-handed with ending threads. And that can threaten my session writes if they occur too near that heavy-handedness.

THE QUESTION:

What about ASP.NET session management makes it so vulnerable to this? The Response.Redirect() line of code doesn't begin its execution until the session write line is "finished" -- how can it be such a threat to my session write?

What about the session write doesn't "finish" before the next line of code executes? Are there other scenarios in which session writes are similarly (as though they never occurred) lost?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

救星 2024-08-28 04:14:26

我对会话写入的内部结构不太熟悉,但我认为它有一些复杂性,因为它依赖于将浏览器会话 cookie 转换为服务器标识。此外,ThreadAbortExceptions 在运行时确实有特殊的考虑,这可能会在这里发挥作用,我不确定。

无论如何,Response.Redirect() 都有一个重载,它采用一个布尔参数,让您指定是否要结束线程。

Response.Redirect(string url,  bool endResponse);

如果您在 endResponse 设置为“false”的情况下调用它,它将正常完成,而不是在内部调用 Thread.Abort()。但是,这意味着它还将在完成之前执行页面生命周期中剩余的任何代码。

一个好的折衷方案是调用 Response.Redirect(url, false),然后调用 Application.CompleteRequest()。这将允许您进行重定向,但也可以通过最少的额外生命周期处理来正常关闭当前执行上下文。

I'm not familiar enough with the internals of session writing, but I imagine it has some complexities, as it relies on translating the browser session cookies into a server identification. Additionally, ThreadAbortExceptions do have special considerations in the runtime, which may play in here, I'm not sure.

In any case, Response.Redirect() has an overload that takes a boolean parameter that lets you specify whether you want to end the thread or not.

Response.Redirect(string url,  bool endResponse);

If you call it with endResponse set to "false", it will gracefully finish, rather than calling Thread.Abort() internally. However, this means it will also execute any code left in the page lifecycle before finishing up.

A good compromise is to call Response.Redirect(url, false) followed by Application.CompleteRequest(). This will allow your redirect to happen but also gracefully shut down the current execution context with a minimal amount of additional lifecycle processing.

只想待在家 2024-08-28 04:14:26

在测试了几种替代方案(Response.Redirect(..., false)、Server.Transfer() 和其他我现在不记得的“解决方案”)之后,我们只找到了这个问题的一个可靠答案。

将会话状态从 InProc 移动到 SqlServer 有效地从我们的系统中消除了这种行为,使 Response.Redirect(...) 完全可靠。如果进一

After testing several alternatives (Response.Redirect(..., false), Server.Transfer(), and other "solutions" I can't now recall), we've found only one reliable answer to this problem.

Moving our session state from InProc to SqlServer effectively eradicated this behavior from our systems, leaving Response.Redirect(...) completely reliable. If further testing shows otherwise, I'll report here, but I say, to make this stop happening in your environment: move your session state into SqlServer (or is "out of InProc" good enough? I'm not sure).

攒眉千度 2024-08-28 04:14:26

应用程序池回收可能会导致您的会话消失。您可以将应用程序池配置为在固定时间进行回收(推荐,在夜间或低使用率期间),或增加应用程序池回收的超时期限。

Application pool recycle can cause your session to go away. You can configure the app pool to recycle at fixed times (recommended, and at night or during low-usage periods) or increase the timeout period of your app pool recycle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文