ASP.NET 会话对象生命周期的悲观假设!

发布于 2024-10-04 13:43:18 字数 322 浏览 4 评论 0 原文

我检查一个 session 对象,如果它确实存在,则调用另一个间接使用该对象的方法。尽管第二种方法将在几纳秒内访问该对象,但我正在考虑对象在两次调用之间恰好过期的情况。 Session 对象是否会在每次从代码读取访问时延长其生命周期以防止此类问题?如果不是怎么解决问题?

如果您要说为什么我不将检索到的对象从第一个方法传递给第二个方法,这是因为我将 ASP.NET Page 对象传递给第二个方法,该对象内部携带许多其他参数如果我尝试分别传递它们中的每一个,则会有很多参数,而我现在只传递一个 Page 对象。

I check a session object and if it does exist then call another method which would use that object indirectly. Although the second method would access this object in a few nanoseconds I was thinking of a situation when the object exactly expires between two calls. Does Session object extends its lifetime on every read access from code for preventing such a problem ? If not how to solve the problem ?

If you are going to say why I don't pass the retrieved object from first method to second one, this is because I pass the ASP.NET Page object which carries many other parameters inside it to second method and if I try to pass each of them separately, there would be many parameters while I just pass one Page object now.

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

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

发布评论

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

评论(3

红焚 2024-10-11 13:43:18

别担心,这不会发生

如果我了解您的情况,它的工作方式如下:

  1. 访问某个页面
  2. 如果会话处于活动状态,它会立即重定向到第二页或在第一页上执行特定方法。
  3. 第二个页面/方法使用会话

您担心会话会在第一个和第二个方法/页面的执行之间过期。

基本上这是不可能的,因为您的会话计时器在第一页开始处理之前when被重置。因此,如果第一个页面有活动会话,那么您的第二个页面/方法也会有它(只要处理在 20 分钟之前完成 - 默认会话超时持续时间)。

会话是如何处理的

会话是通过 HTTP 模块来处理的,该模块在每个请求上以及页面开始处理之前运行。这解释了这种行为。如果您不熟悉 HTTP 模块,那么我建议您阅读一些有关 IHttpModule 接口

Don't worry, this won't happen

If I understand your situation it works sort of this way:

  1. Access a certain page
  2. If session is active it immediately redirects to the second page or executes a certain method on the first page.
  3. Second page/method uses session

You're afraid that session will expire between execution of the first and second method/page.

Basically this is impossible since your session timer was reset when just before the first page starts processing. So if the first page had active session then your second page/method will have it as well (as long as processing finishes before 20 minutes - default session timeout duration).

How is Session processed

Session is processed by means of an HTTP Module that runs on every request and before page starts processing. This explains the behaviour. If you're not familiar with HTTP Modules, then I suggest you read a bit about IHttpModule interface.

月光色 2024-10-11 13:43:18

恕我直言,很难理解你的问题,但我会尝试。

据我了解,您正在做类似的事情:

string helloWorld = string.Empty;
if (this.Session["myObject"] == null)
{
    // The object was removed from the session or the session expired.
    helloWorld = this.CreateNewMyObject();
}
else
{
    // Session still exists.
    helloWorld = this.Session["myObject"].ToString(); // <- What if the session expired just now?
}

或者

// What if the session existed here...
if (this.Session["myObject"] == null)
{
    this.Session["myObject"] = this.CreateNewMyObject();
}

// ... but expired just there?
string helloWorld = this.Session["myObject"].ToString();

我认为 Session 对象由与页面请求相同的线程管理,这意味着检查对象是否存在是安全的,而不是无需 try/catch 即可使用它。

我错了:

对于缓存对象,您必须意识到您实际上是在处理跨多个线程访问的对象这一事实

来源:ASP.NET 缓存和会话状态存储

我也错误地没有仔细阅读 Robert Koritnik 的答案,事实上,它清楚地回答了这个问题。

事实上,系统会警告您在页面请求期间可能会删除对象。但由于 Session 生命周期依赖于页面请求,这意味着您必须考虑删除会话变量仅当您的请求花费的时间超过会话超时(请参阅如何是 Robert Koritnik 的答案中处理的会话)。

当然,这样的情况是非常罕见的。但是,如果在您的情况下,您非常确定页面请求可能需要超过 20 分钟(默认会话超时),那么您必须考虑到在检查对象是否存在后可能会删除该对象,但是在你真正使用它之前。

在这种情况下,您显然可以增加会话超时,或者在访问会话对象时使用 try/catch。但恕我直言,如果页面请求需要数十分钟,您必须考虑其他替代方案(例如 Windows 服务)来完成这项工作。

It's quite difficult to understand your question, IMHO, but I will try.

From what I understand, you're doing something like:

string helloWorld = string.Empty;
if (this.Session["myObject"] == null)
{
    // The object was removed from the session or the session expired.
    helloWorld = this.CreateNewMyObject();
}
else
{
    // Session still exists.
    helloWorld = this.Session["myObject"].ToString(); // <- What if the session expired just now?
}

or

// What if the session existed here...
if (this.Session["myObject"] == null)
{
    this.Session["myObject"] = this.CreateNewMyObject();
}

// ... but expired just there?
string helloWorld = this.Session["myObject"].ToString();

I thought that Session object is managed by the same thread as the page request, which would mean that it is safe to check if object exists, than use it without a try/catch.

I were wrong:

For Cache objects you have to be aware of the fact that you’re dealing essentially with an object accessed across multiple threads

Source: ASP.NET Cache and Session State Storage

I were also wrong about not reading to carefully the answer by Robert Koritnik, which, in fact, clearly answers the question.

In fact, you are warned about the fact that an object might be removed during page request. But since Session lifespan relies on page requests, it would mean that you must take in account the removal of session variables only if your request takes longer than the session timeout (see How is Session processed in the answer by Robert Koritnik).

Of course, such situation is very rare. But if in your case, you are pretty sure that the page request can take longer than 20 minutes (default session timeout), than yes, you must take in account that an object may be removed after you've checked if it exists, but before you really use it.

In this situation, you can obviously increment the session timeout, or use try/catch when accessing the session objects. But IMHO, if the page request takes dozens of minutes, you must consider other alternatives, as Windows services, to do the work.

计㈡愣 2024-10-11 13:43:18

我很难理解这里的问题是什么,但让我再试一次,参考线程安全。

线程安全问题

如果这是一个线程安全问题,您始终可以在创建某个特定对象时发出锁session 对象,这样其他并行请求就不会因为双重创建对象而遇到问题。

if (obj == null)
{
    lock (objLock)
    {
        if (obj == null)
        {
            obj = GenerateYourObject();
        }
    }
}

如果您以前从未使用过,请查看 MSDN 上的锁定文档。并且不要忘记检查其他网络资源。

I'm having difficulties understanding what the problem here is but let me try it again referring to thread safety.

Thread safety issue

If this is a thread safety issue, you can always issue a lock when creating a certain session object so other parallel requests won't run into a problem by double creating your object.

if (obj == null)
{
    lock (objLock)
    {
        if (obj == null)
        {
            obj = GenerateYourObject();
        }
    }
}

Check lock documentation on MSDN if you've never used it before. And don't forget to check other web resources as well.

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