2

我有一个当前使用当前 HttpContext 来存储 LINQ 数据上下文的 Web 应用程序。根据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
}

但是,我有一些从 global.asax 文件执行的脚本,它们没有HttpContext。 HttpContext.Current 是 NULL,因为服务器是发出“请求”的服务器。

是否有可用于存储数据上下文的等效对象?所以我不必担心重新创建它和附加/分离对象?我只想在我的流程的整个生命周期中保留上下文。

更新:

我目前正在尝试在我的 DAL 助手类中使用静态变量。在第一次调用类中的一个方法时,DataContext 被实例化,并存储在静态变量中。在我的过程结束时,我调用另一个在 DataContext 上调用 Dispose 的方法,并将静态变量设置为 NULL。

4

5 回答 5

4

你能不能只为那些脚本专门使用一个静态变量?这将具有与AppDomain. 您可能应该仔细考虑任何并发问题,但这听起来像是保持价值的最简单方法。

(我刚刚检查过,虽然一个实例HttpApplication可用于服务多个请求,但每个实例一次只处理一个请求 - 这表明为并发请求处理创建了多个实例。我尚未对此进行验证,但是听起来确实将其保存在实例变量中并不安全。)

编辑:乔希的回答表明你希望这是每个线程。这对我来说听起来有点奇怪,因为除非您发生了很多这样的事件,否则您很可能只会看到它们在不同的线程上执行,从而使整个共享业务毫无意义。如果你真的想要那种东西,我建议只在HttpApplication-derived 类中使用一个实例变量 - 正是上面段落中描述的原因:)

于 2009-03-31T19:37:48.760 回答
1

Why not use the current 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.

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. Because of that, the key is pretty much worthless when it's based on the instance of HttpContext and the thread.

Also, how do you dispose of the DataContext when you are done? It implements IDisposable for a reason, so I would recommend against a shared instance like this.


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. Then you will always have an HttpContext to work with.

于 2009-03-31T19:39:28.320 回答
0

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.

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. 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.

I would also recommend that you consider moving the logic out of your global.asax and to a windows service. This would let you have more control over these tasks, for example you can shut them down seperatley of the web site.

Edit

As JS points out you could use a static variable. You could also define an instance variable marked with ThreadLocal attribute. 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.

于 2009-03-31T19:40:45.417 回答
0

Is there a reason why these need to be handled the same way as the other 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.

于 2009-03-31T19:45:24.763 回答
0

Set the DataContext as the state parameter when creating the timer. 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.

Also avoid using the same DataContext for different timers, because you would end up with mixed modifications from the different timers. Also make sure your same timer logic isn't run twice, since it would cause the same i.e. too short period with no control.

于 2009-04-01T00:27:38.347 回答