在我的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;
}
}
答案 0 :(得分:3)
考虑到您的扩展版本,DerviedClass
的示例:我会说,这是一个非常危险的问题,可能会导致很多问题。
我的担忧:
1)ASP。NET
+ NHibernate
== ISession
每请求。换句话说,当应用程序启动时(最有可能通过第一个请求触发,如果自动重启就可能更频繁),将创建Singleton并提供ISession
的实例每当前请求即第一次请求。
至少,ISession
应该在需要时通过Factory
收到,以确保它与当前请求相关。
2)如果在构造函数中创建的NHibernate 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();