如何使这个线程安全
Posted
技术标签:
【中文标题】如何使这个线程安全【英文标题】:How to make this thread-safe 【发布时间】:2011-07-18 05:08:07 【问题描述】:我有以下用于 Fluent NHibernate 的 SessionFactory。
我收到一个错误
创建 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;
【问题讨论】:
【参考方案1】:通常的方法是创建一个只允许单次访问的互斥体(可能在您的公共方法中)。见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;
【讨论】:
谢谢,我试试看。 @IamStalker:什么不起作用?使用演示问题的代码发布一个新问题。另一种可行的方法是使用“锁定”,但这仅适用于单个进程(及其线程),而不适用于系统范围。以上是关于如何使这个线程安全的主要内容,如果未能解决你的问题,请参考以下文章