我有一个问题.在我的网络应用程序中,我有一个页面,启动另一个线程,耗时的任务.在这个新线程中,我调用了一个我的架构方法(在另一个项目中 - 一个架构项目).问题是:在其中一种方法中,我访问了一个HttpContext.Current.Session字段.但是当我启动应用程序时,会抛出一个异常,说该对象(HttpContext.Current.Session)有一个空引用.我怎么能设置新线程的上下文与HttpApplication上下文相同才能访问HttpContext.Current.Session?
这里有很多事情需要考虑.
如果你的线程的生命周期与页面的生命周期相等,并且你需要对它进行大量的随机访问HttpSessionState,那么你应该SynchronizationContext从使用static Current属性创建后台线程的调用中获取.
一旦你的,你可以传递给你的线程,然后当你需要访问任何在HttpContextBase与请求相关联(这包括会话),你可以调用Post方法对SynchronizationContext您传递给你的线程得到的值是(或设置它们):
// From thread servicing request.
var sc = SynchronizationContext.Current;
// Run the task
Task t = Task.Run(() => {
// Do other stuff.
// ...
// The value to get from the session.
string sessionValue = null;
// Need to get something from the session?
sc.Post(() => {
// Get the value.
sessionValue = HttpContext.Current.Session["sessionValue"];
}
// Do other stuff.
// ...
});
Run Code Online (Sandbox Code Playgroud)
这样做很重要,因为对HttpContextBase(和与之相关的任何东西)的访问不是线程安全的,并且与处理请求的线程(井,上下文)相关联.
请注意,该Post方法不会阻塞,因此调用之后的代码Post(即后面的行// Do other stuff.)应该独立于传递给的委托Post.如果后面的代码是相关的,你需要在继续之前等待调用完成,那么你可以调用该Send方法 ; 它具有相同的签名,并将阻塞,直到委托中的代码被执行.
也就是说,如果您只想对值进行只读访问,那么最好在调用代码之前获取它们,然后在后台线程中访问它们:
// Get the values needed in the background thread here.
var values = {
SessionValue = HttpContext.Current.Session["sessionValue"];
};
// Run the task
Task t = Task.Run(() => {
// Do other stuff.
// ...
// Work with the session value.
if (values.SessionValue == ...)
// Do other stuff.
// ...
});
Run Code Online (Sandbox Code Playgroud)
如果您的线程在服务请求后将继续处理,那么您只有只读状态,并且必须在启动线程之前捕获它.一旦请求得到服务,即使会话存在,这也是一个合乎逻辑的概念; 根据会话状态的提供者(会话状态管理器,SQL Server等),每次有新请求进入时,对象都可以被水合.
您还必须处理会话超时问题,您不知道会话是否存在于您想要访问它的位置.
| 归档时间: |
|
| 查看次数: |
10901 次 |
| 最近记录: |