NHibernate有时启动缓慢

本文关键字:缓慢 启动 NHibernate | 更新日期: 2023-09-27 18:16:23

我在一个新的桌面项目中使用NHibernate 3。我读过关于序列化配置对象的文章。我这样做了,但有时它不起作用。我开始认为只有当我启动应用程序(序列化配置对象),然后关闭它,并再次启动(几秒钟后)时,它才会工作。但是如果我等几分钟,它就不起作用了。我说的是45秒以上。另一件奇怪的事情是,如果这只发生在一些机器上,而不是全部。有些工作如预期的第一次缓慢,但在下一次启动时更快。

下面是我的配置:

创建配置和会话工厂的类

class NHibernateUnitOfWorkFactory : IUnitOfWorkFactory
    {
        public NHibernateUnitOfWorkFactory(string nhibernateConfigPath)
        {
            String serializablefilePath = "configuration.serialized";
            try
            {
                if (IsConfigurationFileValid(serializablefilePath))
                {
                    Configuration = LoadConfigurationFromFile(serializablefilePath);
                }
                else
                {
                    // configuration is immutable, store last returned value
                    Configuration = new Configuration();
                    Configuration.Configure(nhibernateConfigPath);
                    Configuration.AddAssembly(typeof(ObjectEntity).Assembly);
                    SaveConfigurationToFile(serializablefilePath, Configuration);
                    new SchemaUpdate(Configuration).Execute(true, true);
                }
                //NHibernateSchemaExport();
            }
            catch (Exception ex)
            {
                throw new GenericRepositoryException(
                    string.Format("Error while configuring NHibernate: {0}.", ex.Message)
                    , ex
                    );
            }
            try
            {
                SessionFactory = Configuration.BuildSessionFactory();
            }
            catch (Exception ex)
            {
                throw new GenericRepositoryException(
                    string.Format("Error while building NH session factory: {0}.", ex.Message)
                    , ex
                    );
            }
        }
        private Boolean IsConfigurationFileValid(String ConfigFile)
        {
            //return File.Exists(ConfigFile);
            var ass = typeof(ObjectEntity).Assembly; //Assembly.GetCallingAssembly();
            if (ass.Location == null)
                return false;
            var configInfo = new FileInfo(ConfigFile);
            var assInfo = new FileInfo(ass.Location);
            if (configInfo.LastWriteTime < assInfo.LastWriteTime)
                return false;
            return true;
        }
        private static void SaveConfigurationToFile(String ConfigFile, Configuration configuration)
        {
            var file = File.Open(ConfigFile, FileMode.Create);
            var bf = new BinaryFormatter();
            bf.Serialize(file, configuration);
            file.Close();
        }
        private static Configuration LoadConfigurationFromFile(String ConfigFile)
        {
            try
            {
                var file = File.Open(ConfigFile, FileMode.Open);
                var bf = new BinaryFormatter();
                var config = bf.Deserialize(file) as Configuration;
                file.Close();
                return config;
            }
            catch (Exception)
            {
                return null;
            }
        }
        protected ISessionFactory SessionFactory { get; private set; }
        protected Configuration Configuration { get; private set; }
        /// <summary>
        /// Generates table structure inside specified database.
        /// </summary>
        public void NHibernateSchemaExport()
        {
            new SchemaExport(this.Configuration).Execute(false, true, false);
        }
        #region IUnitOfWorkFactory Members
        public IUnitOfWork BeginUnitOfWork()
        {
            return new NHibernateUnitOfWork(this.SessionFactory.OpenSession());
        }
        public void EndUnitOfWork(IUnitOfWork unitOfWork)
        {
            var nhUnitOfWork = unitOfWork as NHibernateUnitOfWork;
            if (unitOfWork != null)
            {
                unitOfWork.Dispose();
                unitOfWork = null;
            }
        }
        #endregion
        #region IDisposable Members
        public void Dispose()
        {
            if (this.SessionFactory != null)
            {
                (this.SessionFactory as IDisposable).Dispose();
                this.SessionFactory = null;
                this.Configuration = null;
            }
        }
        #endregion
    }
xml配置

<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <reflection-optimizer use="true"/>
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="connection.connection_string">
      User Id=xx;
      Password=xx;
      Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=
      (PROTOCOL=TCP)(HOST=192.168.100.xx)(PORT=1521)))
      (CONNECT_DATA=(SERVICE_NAME=XE)));
    </property>
    <property name="show_sql">false</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <property name="cache.use_query_cache">false</property>
    <property name="cache.use_second_level_cache">false</property>
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
  </session-factory>
</hibernate-configuration>

有什么改进启动时间的方法吗?

NHibernate有时启动缓慢

序列化只加速构建配置(config = new Configuration().Add... vs config = bf.Deserialize(file)),而不是构建sessionfactory,后者做了许多其他的事情,如生成代理,连接到数据库等。很可能是连接到服务器的速度太慢,或者是导致延迟的服务器速度太慢。

当异常发生时,最好使用using来防止泄漏FileHandles

using (var file = File.Open(ConfigFile, FileMode.Open))
{
    var bf = new BinaryFormatter();
    return bf.Deserialize(file) as Configuration;
}