NHibernate 如何在并行线程下,使用session

第一,你要知道,并行线程会有一个蛋疼的地方。他不会每次执行都给你去开一个线程。

我一开始以为每次执行都会去开一个新的线程。。。。

list.AsParallel().ForAll(memberInfo =>

{
   Console.WriteLine(Thread.GetCurrentProcessorId());

}

result

这就导致,如果我们在当前线程上下文绑定了sessionFactory就会导致,重用线程会获取到一样的session

如果在前面一个线程中我们关闭了session 就会导致后来获取到的session失效。

第一个, 我们首先去配置 SessionFactory

NHibernate.Cfg.Configuration的实例化对象Configuration

设置SessionFactory的配置属性

Configuration.SetProperty("current_session_context_class", "thread_static"); //每个线程获取到的session是不一样的。

然后更改获取session的方法

当然要在方法外部设置一个静态的session  并且要带上线程静态的标签,那么每个线程获取的去获取的时候是原来的那一个,这就涉及到关闭了

[ThreadStatic]
private static ISession Session;

public ISession OpenCurrentSession()
{
    try
    {
         if(CurrentSessionContext.HasBind(SessionFactory))
         {
               Session = SessionFactory.GetCurrentSession();
         }
         else
         {
               Session = SessionFactory.OpenSession();
               CurrentSessionContext.Bind(Session);
         }
         return Session;
     }
     catch
     {
          throw;
     }
}

关闭session方法 

public void CloseCurrentSession()
{
    try
    {
        //一定要线程上下文解绑 否则重用线程将会取到已经关闭的session 
        CurrentSessionContext.Unbind(Session.SessionFactory);
        Session.Close();
        Session.Dispose();
    }
    catch
    {
        throw;
     }
}          

//至于查询方法 ,你可以把你的sessionFactory使用 单例,

然后重ioc容器中去取

list.AsParallel().ForAll(memberInfo =>
{
    Console.WriteLine(Thread.GetCurrentProcessorId());
    var session = appSessionFactory.OpenCurrentSession();
    //这里进行查询 我不建议在这里取使用更新删除插入操作,很容易出问题
    appSessionFactory.CloseCurrentSession();
});

这个并行线程使用session 就差不多完了。

一般用于多个去做一件事的时候可以用到并行线程,比如我需要集合中的每个元素都要去查数据库,如果用for循环,会非常慢,如果用并行,将会非常快。

 

posted @ 2018-06-07 10:09  无语1994  阅读(733)  评论(0编辑  收藏  举报