有时NHibernate慢启动

时间:2011-12-02 13:48:54

标签: c# nhibernate

我在一个新桌面项目上使用NHibernate 3。我已阅读有关序列化配置对象的信息。我做到了,但有时它不起作用。我开始认为它只在我启动应用程序(序列化配置对象),然后关闭它,然后再次启动(几秒钟后)时才起作用。但如果我等了几分钟它就行不通了。我说的是45秒以上。其他奇怪的事情,如果这只发生在几台机器上,而不是全部。有些工作如预期的那样第一次变慢,但nexts初创公司的速度更快。

这是我的配置:

创建配置和会话工厂的类

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>

有什么想法可以改善启动时间吗?

1 个答案:

答案 0 :(得分:1)

序列化只会加快构建配置(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;
}