How to make this thread safe

I have the following SessionFactory for Fluent NHibernate.

I get an error

An invalid or incomplete configuration was used when creating the SessionFactory.

with InnerException

An item with the same key has already been added.

This problem occurs only occasionally, and my application works fine in most cases.

Based on NHibernate: System.Argument Exception: an element with the same key has already been added. I assume that my class is not thread safe, which explains the intermittent nature of this error.

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; } } } 
+4
source share
1 answer

The usual approach is to create a mutex (possibly in your public method) that allows only one access. See http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx

Not tested as a compilation, but something like:

  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; } 
+5
source

Source: https://habr.com/ru/post/1344276/


All Articles