2012-01-10 152 views
3

请注意,“singleton”在稍微不常见的意义上使用 - “与HttpContext.Current类似的单个实例可见的对象”不同于普通的“具有一个共享实例的对象”。这个“单例”应该在ASP.NET应用程序中是线程安全的吗?

我使用单身类型UserContext类为我的asp.net MVC应用程序。这个类允许我将用户数据存储为强类型的会话对象。我碰到了this CodeReview question,并想知道在这个应用环境中是否有必要关心线程安全。

这里是我的代码的简化:

public class UserContext 
{ 
    private UserContext() 
    { 
    } 

    public static UserContext Current 
    { 
     get 
     { 
      if (HttpContext.Current.Session["UserContext"] == null) 
       BuildUserContext(); 

      return (UserContext)HttpContext.Current.Session["UserContext"]; 
     } 
    } 

    private static void BuildUserContext() 
    { 
     if (!user.Identity.IsAuthenticated) return; 

     var uc = new UserContext { IsAuthenticated = true }; 

     // ...snip... 
     // Set up user data 

     // Save it into the session 
     HttpContext.Current.Session["UserContext"] = uc; 
    } 


    #region Class members 
    public bool IsAuthenticated { get; internal set; } 
    public string Name { get; internal set; } 
    // ...snip... 
    // Other properties 

    public void Refresh() 
    { 
     BuildUserContext(); 
    } 

    public void Flush() 
    { 
     HttpContext.Current.Session["UserContext"] = null; 
    } 
    #endregion 
} 

我没有任何锁定的问题,到目前为止,但现在该网站是不是很高的流量。我应该采用Jon Skeet的线程安全模型吗?还是IIS管理我?

+0

你的样本中“singleton”在哪里?代码是合理的,但是对象不是以任何常规意义上的“单例”(具有一个实例的对象 - http://en.wikipedia.org/wiki/Singleton_pattern)...如果实际用作单例,这将是一个巨大的问题。 – 2012-01-10 17:06:22

+0

是的,在标题中加入单词“singleton”之前我实际上已经暂停了,但是我没有更有效的方式来描述它。在会话的上下文中它是一个单例,但是你是对的,它不是一个应用程序范围的单例。我的问题更多地是关于如何处理线程,以及这是否会造成问题。 – 2012-01-10 17:09:58

回答

2

访问Session已经是线程安全的。

一般而言,只要您以线程安全的方式访问静态属性中的任何共享状态,就不会有任何问题。

1

ASP会话状态带有同步逻辑。 如果执行的页面需要对会话状态的写入访问权限,则会话状态将被锁定,并且同一会话上的其他请求必须等到第一个请求完成。

请参阅Synchronizing Access to the Session State