代码之家  ›  专栏  ›  技术社区  ›  DaveDev

需要帮助识别一个微妙的错误。。在IIS中?会议?其他地方。。?

  •  1
  • DaveDev  · 技术社区  · 14 年前

    背景: 我们有两个网站在同一个web服务器上运行同一个应用程序。

    • SiteA—访问者www.SiteA.com
    • SiteB—访问者www.SiteB.com

    当请求第一次传入时,将根据主机标识siteId,并将其存储在会话中,如下所示:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string host = Request.Url.Host;
        int siteId = new SiteManager().GetSiteByUrl(host).SiteId;
        if (SessionUser.Instance().SiteId != siteId)
        {
            SessionUser.Instance().SiteId = siteId;
        }
    }
    

     // this happens during an initialization phase
     _siteConfiguration = _siteManager.GetSiteById(SessionUser.Instance().SiteId);
    
    // then later:
    private void SetPageTheme()
    {
        string theme = null;
    
        switch (_siteConfiguration.SiteId)
        {
            case ConfigurationHelper.SITE.A:
                theme = "SiteATheme";
                break;
            case ConfigurationHelper.SITE.B:
                theme = "SiteBTheme";
                break;                
        }
    
        Page.Theme = theme;
    }
    

    问题是:

    我面临的问题是如果你同时加载两个站点 几乎 完全相同的时间,即毫秒内,有时SiteA会加载SiteB的主题,反之亦然。这种情况并不经常发生,但已经引起客户的注意,所以现在是个问题。。在SiteA加载和SiteB加载之间的差异中,在这几毫秒内的某个地方发生了一些事情,我不知道如何确定这是什么。

    有人知道这里出了什么问题吗?有什么地方搞混了。是不是把请求搞混了?是会话混淆了它应该返回SiteId的站点吗?

    如果需要更多的信息,我会提供的。

    更新:

    SessionUser

    public class SessionUser
    {
        private static SessionUser _instance;
    
    
        public int SiteId { get; set; }
    
    
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static SessionUser Instance()
        {
            if (null == _instance)
            {
                _instance = new SessionUser();
    
                if (null != HttpContext.Current.Session)
                {
                    if (null == HttpContext.Current.Session["User"])
                    {
                        if (HttpContext.Current.Request.QueryString["sid"] != null)
                        {
                            int nSiteId = int.Parse(HttpContext.Current.Request.QueryString["sid"]);
                            _instance.SiteId = nSiteId;
    
                            HttpContext.Current.Session["User"] = _instance;
    
                        }
                    }
                    else
                    {
                        _instance = (SessionUser) HttpContext.Current.Session["User"];
                    }
                }
            }
    
            return _instance;
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   leppie    14 年前

    我将假设SessionUser.Instance()返回一个“static”实例(或者更确切地说是成员)。

    现在,这些将在整个应用程序中共享。所以这是有道理的,这不能在两个网站之间共享。

    我建议你还是用 HttpContext BeginRequest

    代码将如下所示:

    class SessionUser
    {
      public static SessionUser Instance()
      {
        var ctx = HttpContext.Current;
        var su = ctx["SessionUser"] as SessionUser;
        if (su == null)
        {
          ctx["SessionUser"] = su = new SessionUser();
        }
        return su;
      }
    }
    
        2
  •  0
  •   Community kfsone    7 年前

    我想您可以将存储当前站点ID的代码放在 lock 块,但这可能会妨碍性能。使用两个站点都不共享的东西更有意义,例如 leppie says

    对于锁示例:

    if (SessionUser.Instance().SiteId != siteId)
    {
        lock(somePrivateStaticObject)
        {
            if (SessionUser.Instance().SiteId != siteId)
            {
                SessionUser.Instance().SiteId = siteId;
            }
        }
    }