2011-03-18 63 views
4

我有以下用于流利NHibernate的SessionFactory。如何使这个线程安全

我得到的

一个无效或不完整的配置错误,同时创建一个会话使用。

一个项目的InnerException使用相同的密钥已被添加。

这个问题只是偶尔发生,我的应用程序大多数时候工作正常。

根据NHibernate: System.Argument Exception : An item with the same key has already been added我猜我的班级不是线程安全的,这将解释此错误的间歇性。

using System; 
using NHibernate; 
using NHibernate.Cache; 
using NHibernate.Cfg; 
using FluentNHibernate.Cfg; 
using FluentNHibernate.Cfg.Db; 
using WSS.Data.Domain; 

namespace WSS.Data { 
    public static class SessionFactory { 
     private static ISessionFactory _factory = null; 
     private static ISessionFactory GetFactory() { 
      if (_factory == null) { 
       NHibernate.Cfg.Configuration config; 
       config = new NHibernate.Cfg.Configuration(); 
       config.Configure(); 
       if (config == null) { 
        throw new InvalidOperationException("NHibernate configuration is null."); 
       } 


       config.AddAssembly("WSS.Data"); 
       _factory = config.BuildSessionFactory(); 
       if (_factory == null) { 
        throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null."); 
       } 
      } 
      return _factory; 

     } 

     private static ISessionFactory GetFluentFactory() { 
      if(_factory == null) { 
       _factory = Fluently.Configure() 
        .Database(MsSqlConfiguration.MsSql2000 
         .ConnectionString(c => c 
          .Is(ConnectionStrings.Auto)) 
         .Cache(c => c 
          .UseQueryCache() 
          .ProviderClass()) 
         .ShowSql()) 
        .Mappings(m => m 
         .FluentMappings.AddFromAssemblyOf()) 
        .BuildSessionFactory(); 
      } 

      return _factory; 
     } 

     public static ISession OpenSession() { 
      ISession session; 
      session = GetFluentFactory().OpenSession(); 
      if (session == null) { 
       throw new InvalidOperationException("Call to factory.OpenSession() returned null."); 
      } 
      return session; 
     } 
    } 
}

回答

5

通常的做法是创建一个只允许单一访问的互斥锁(可能在您的公共方法中)。见http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx

没有测试中编译,但这样的:

private static Mutex _sessionMutex = new Mutex(); 

    public static ISession OpenSession() { 
     ISession session; 

     _sessionMutex.WaitOne(); 

     session = GetFluentFactory().OpenSession(); 
     if (session == null) { 
      throw new InvalidOperationException("Call to factory.OpenSession() returned null."); 
     } 

     _sessionMutex.ReleaseMutex(); 
     return session; 
    } 
+0

谢谢,我给一个尝试。 – modernzombie 2011-03-18 14:34:21

+0

这对我不起作用......你建议什么? – IamStalker 2014-01-29 14:58:37

+0

@IamStalker:什么不行?用演示问题的代码发布新问题。可以工作的另一种方法是使用“锁定”,但只适用于单个进程(及其线程)而不是系统范围。 – 2014-01-29 17:17:28