ASP.NET多线程是否影响Structuremap单例类?

时间:2013-06-04 13:47:06

标签: c# thread-safety singleton structuremap

在我的ASP.NET MVC项目中,我有一个类,它通过Structuremap实例化,并配置为单例。

鉴于ASP.NET本质上是多线程的,并且默认情况下Singleton模式不是线程安全的,它会导致任何问题吗?

我遇到了一个问题,即为配置为Singleton的类返回了多个实例。这个问题可能是因为从不同的线程请求实例。

编辑:对此问题给出了更详细的描述。Structuremap in Singleton returning multiple instances

EDIT2:这是我班级做什么的描述

class DerviedClass: BaseInterface
{
   ISession session

   DerivedClass()
   {
      session = ObjectFactory.GetInstance<ISession>();
   }

   public bool DoWork
   {
       return session.QueryOver<MyTable>().RowCount() > 0;
   }
}

2 个答案:

答案 0 :(得分:3)

考虑到您的扩展版本,DerviedClass的示例:我会说,这是一个非常危险的问题,可能会导致很多问题。

我的担忧:

1)ASP。NET + NHibernate == ISession请求。换句话说,当应用程序启动时(最有可能通过第一个请求触发,如果自动重启就可能更频繁),将创建​​Singleton并提供ISession的实例每当前请求第一次请求

至少,ISession应该在需要时通过Factory收到,以确保它与当前请求相关。

2)如果在构造函数中创建的NHibernate ISession旨在独立于当前请求,则可能意味着:

  • 在更多请求中长时间运行,打开和未关闭 - 可能的锁定问题。或者
  • 需要一些开放/关闭的ISession管理,而不是基于当前的请求

关键是,我没有看到Singleton模式的好处。我们不需要也不提供共同的,请求独立的东西。

我们确实返回依赖于请求(及其会话范围)的数据。那么,我建议使用什么:

.HybridHttpOrThreadLocalScoped()

每个请求创建实例的开销与逻辑生命周期使用的好处相比没什么用。

但是,是的,这只是我的建议......因为我看到很多潜在的问题(锁定,无意改变会话中的脏对象,可以提交等等)。

答案 1 :(得分:1)

您必须通过确保每个属性集块都使用锁来使单例线程安全,如下所示:

public int Counter
{
    get { return _counter; }

    set
    {
        lock(_counterLock)
        {
            _counter = value;
        }
    }
}

private int _counter = 0;

private object _counterLock = new Object();