简体   繁体   English

HttpContext 的服务器端等价物?

[英]Server-side equivalent of HttpContext?

I have a web app that currently uses the current HttpContext to store a LINQ Data Context.我有一个 web 应用程序,它当前使用当前的 HttpContext 来存储 LINQ 数据上下文。 The context is persisted for the current request, on a per user basis, per Rick Strahl's blog :根据Rick Strahl 的博客,基于每个用户的当前请求的上下文是持久的:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x")  
Thread.CurrentContext.ContextID.ToString();

if (!HttpContext.Current.Items.Contains(ocKey))
{
    // Get new Data Context and store it in the HTTP Context
}

However, I have some scripts that execute from the global.asax file, that don't have an HttpContext.但是,我有一些从 global.asax 文件执行的脚本,它们没有HttpContext。 The HttpContext.Current is NULL , because the server is the one making the "request". HttpContext.Current 是 NULL ,因为服务器是发出“请求”的那个。

Is there an equivalent object that I can use to store the Data Context?是否有等效的 object 可用于存储数据上下文? So I don't have to worry about re-creating it, and attaching/detaching objects?所以我不必担心重新创建它和附加/分离对象? I only want to persist the context for the lifetime of my processes.我只想在我的流程的整个生命周期中保留上下文。

UPDATED:更新:

I am currently trying to use a static variable in my DAL helper class.我目前正在尝试在我的 DAL 助手 class 中使用 static 变量。 on the first call to one of the methods in the class the DataContext is instantiated, and stored in the static variable.在第一次调用 class 中的一个方法时,DataContext 被实例化,并存储在 static 变量中。 At the end of my process, I call another method that calls Dispose on the DataContext, and sets the static variable to NULL.在我的过程结束时,我调用另一个在 DataContext 上调用 Dispose 的方法,并将 static 变量设置为 NULL。

Can you not just use a static variable specifically for those scripts?你能不能只为这些脚本使用 static 变量? That will have the same life-time as the AppDomain .这将具有与AppDomain相同的生命周期。 You should probably think carefully about any concurrency concerns, but it sounds like the simplest way to keep a value around.您可能应该仔细考虑任何并发问题,但这听起来像是保持价值的最简单方法。

(I've just checked, and although one instance of HttpApplication can be used to service multiple requests, each one only serves one request at a time - which suggests that multiple instances are created for concurrent request processing. I haven't validated this, but it does sound like it wouldn't be safe to keep it in an instance variable.) (我刚刚检查过,虽然HttpApplication的一个实例可用于服务多个请求,但每个实例一次只服务一个请求 - 这表明为并发请求处理创建了多个实例。我尚未对此进行验证,但听起来确实将其保存在实例变量中并不安全。)

EDIT: Josh's answer suggests that you want this to be per-thread.编辑:乔希的回答表明你希望这是每个线程。 That sounds slightly odd to me, as unless you've got a lot of these events occurring, you're quite likely to only ever see them execute on different threads, making the whole sharing business pointless.这对我来说听起来有点奇怪,因为除非您发生了很多这样的事件,否则您很可能只会看到它们在不同的线程上执行,从而使整个共享业务毫无意义。 If you really do want that sort of thing, I'd suggest just using an instance variable in the HttpApplication -derived class - for exactly the reason described in the paragraph above:)如果你真的想要那种东西,我建议只在HttpApplication派生的 class 中使用一个实例变量 - 正是上面段落中描述的原因:)

Why not use the current HttpContext?为什么不使用当前的 HttpContext? The scripts in your global.asax file are all the result of a request coming into the server, so there should be a context associated with that request which you can grab. global.asax 文件中的脚本都是请求进入服务器的结果,因此应该有一个与该请求相关联的上下文,您可以获取该上下文。

I don't understand the need for generating the key based on the hashcode or the thread.我不明白需要根据哈希码或线程生成密钥。 There is going to be a separate instance of HttpContext for each request that comes in, and that instance is going to be specific to the thread that is processing the request.每个传入的请求都会有一个单独的 HttpContext 实例,并且该实例将特定于处理请求的线程。 Because of that, the key is pretty much worthless when it's based on the instance of HttpContext and the thread.因此,当它基于 HttpContext 的实例和线程时,密钥几乎毫无价值。

Also, how do you dispose of the DataContext when you are done?另外,完成后如何处理 DataContext? It implements IDisposable for a reason, so I would recommend against a shared instance like this.它实现 IDisposable 是有原因的,所以我建议不要使用这样的共享实例。


UPDATE更新

In the comments, it indicates that there is a timer that is running that is executing the scripts.在评论中,它表明有一个正在运行的计时器正在执行脚本。 Instead of the timer, I would recommend setting up a Scheduled Task which will call a webservice or predetermined page on the site which will perform the task.我建议不要设置计时器,而是设置一个计划任务,该任务将调用网站上的 Web 服务或预定页面来执行该任务。 Then you will always have an HttpContext to work with.然后,您将始终有一个 HttpContext 可以使用。

HttpContext.Current is a static method and should be available from anywhere as long as the code is executing within the context of a request. HttpContext.Current 是一个 static 方法,只要代码在请求的上下文中执行,就应该可以在任何地方使用。

In your case your not executing within the context of a request, You could look at using Application.Cache but I would caution against holding a DataContext open.在您的情况下,您没有在请求的上下文中执行,您可以查看使用 Application.Cache 但我会警告不要保持 DataContext 打开。 I am not very famillar with linq to entities, so I could be wrong, but generally caching data base related items such as connections is bad.我对实体的 linq 不是很熟悉,所以我可能是错的,但通常缓存与数据库相关的项目(如连接)是不好的。

I would also recommend that you consider moving the logic out of your global.asax and to a windows service.我还建议您考虑将逻辑移出 global.asax 并移至 windows 服务。 This would let you have more control over these tasks, for example you can shut them down seperatley of the web site.这将使您可以更好地控制这些任务,例如,您可以将它们关闭 web 站点的单独。

Edit编辑

As JS points out you could use a static variable.正如 JS 指出的那样,您可以使用 static 变量。 You could also define an instance variable marked with ThreadLocal attribute.您还可以定义一个标有 ThreadLocal 属性的实例变量。 This will give each thread its own copy of the variable, and can eliminate contention.这将为每个线程提供自己的变量副本,并且可以消除争用。 Since you want each thread to have its own copy anyways.因为您希望每个线程都有自己的副本。

Is there a reason why these need to be handled the same way as the other DataContexts?是否有理由需要以与其他 DataContexts 相同的方式处理这些? It seems to me that if the context is only needed inside the event handling routine, you shouldn't need to keep it around.在我看来,如果仅在事件处理例程中需要上下文,则不需要保留它。 Especially if it is in Application_Start (as per your comment), I wouldn't bother caching it anywhere -- just use it locally and pass it to the other methods as needed.特别是如果它在 Application_Start 中(根据您的评论),我不会费心在任何地方缓存它——只需在本地使用它并根据需要将它传递给其他方法。

Set the DataContext as the state parameter when creating the timer.创建定时器时,将 DataContext 设置为 state 参数。 Based on the info you posted on the comments, it seems to me that your DataContext is more related to the timers than anything else.根据您在评论中发布的信息,在我看来,您的 DataContext 与计时器的关系比其他任何东西都多。

Also avoid using the same DataContext for different timers, because you would end up with mixed modifications from the different timers.还要避免对不同的计时器使用相同的 DataContext,因为您最终会得到来自不同计时器的混合修改。 Also make sure your same timer logic isn't run twice, since it would cause the same ie too short period with no control.还要确保您的相同计时器逻辑没有运行两次,因为它会导致相同的时间,即时间太短而无法控制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM