代码之家  ›  专栏  ›  技术社区  ›  Soonts

ASP.NET+线程感知非托管API

  •  1
  • Soonts  · 技术社区  · 14 年前

    在这一点上这只是我的爱好项目,所以要求是非常灵活的。不过,我希望它能在Windows7、Windows2008和2008R2上工作,并具有.NET3.5和更高版本,以及默认的IIS设置。

    在ESENT中,大多数操作都需要打开会话对象。文档中说:“会话跟踪它在哪个线程上使用,如果在多个线程上使用一个打开的事务,它将抛出一个错误。”API文档中提到了本机线程,而不是托管线程。

    我假设opensession操作相对昂贵,这就是为什么我不想为每个HTTP请求打开/关闭会话。

    在asp.net中,如何在每个执行C代码的本机线程上初始化/取消初始化一次?

    用BeginThreadAffinity方法将asp.net托管线程不断地固定到本机线程上,有什么不好的地方我不知道吗?难道我的会话泄漏后,IIS是在负载下一个月没有一个单一的重新启动?

    提前谢谢!

    class MySession: IDisposable
    {
        [ThreadStatic]
        private static MySession s_session = null;
    
        public static MySession instance
        {
            get
            {
                return s_session ?? ( s_session = new MySession() );
            }
        }
    
        private MySession()
        {
            Thread.BeginThreadAffinity();
            // Open a new session, store the handle in non-static data member.
        }
    
        void IDisposable.Dispose()
        {
            // Close the session.
            Thread.EndThreadAffinity();
        }
    }
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   Laurion Burchall    14 年前

    一个好的方法是创建一个会话池,让线程从池中获取一个会话,然后在完成后返回会话。一个会话可以由不同的线程使用,但是如果您在线程之间迁移会话,ESENT会抱怨 当事务处于活动状态时

    几个使用ESENT的大型服务器应用程序都采用了会话池的方法,对它们来说效果很好。

        2
  •  1
  •   staalp    14 年前

    我们目前的研究表明,在pageu load中实例化一个新会话并在pageu unload中处理它,对于一个在索引上查找的简单脚本,wcat很容易产生600个请求/秒,并且对每个返回的行执行另外两个查找。

    上面的例子是maxsessions设置为256。调整最小缓存大小也有助于提高性能。在具有8gb内存的四核测试服务器上。

        3
  •  0
  •   Andras Vass    14 年前

    如果您真的打算在请求之间保持会话打开,那么这种方式可能不起作用。
    终结器将在单独的线程上运行,关闭会话将引发错误。
    JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly 在里面 JetEndSession() 在Dispose()期间。

    如果您真的必须使用ESENT,也许您可以手动启动和管理一个专用的线程池,并封送对它们的调用。