我正在考虑一个使用ESENT持久性的ASP.NET应用程序。
在这一点上,这只是我的爱好项目,所以要求非常灵活。 不过,我希望它可以在Windows 7,Windows 2008和2008 R2,.NET 3.5及更高版本,以及默认的IIS设置。
在ESENT中,大多数操作要求您打开会话对象。 该文档说:“一个会话跟踪它使用的是哪个线程,如果在多个线程上使用一个打开的事务,它将会抛出一个错误。 API文档提到了本地线程,而不是托pipe线程。
我假设开放会话操作是相对昂贵的,这就是为什么我不想为每个HTTP请求打开/closures会话。
这是我的问题,最后。
在asp.net中,如何在执行我的C#代码的每个本地线程上初始化/取消初始化一次?
下面的代码会贴在下面为我工作吗?
有没有什么不好的,我不知道在保持asp.net托pipe线程不断固定到本地线程与BeginThreadAffinity方法? 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(); } }
一个好办法是创建一个会话池,让线程从池中获取会话,然后在完成时返回会话。 会话可以被不同的线程使用,但是如果在事务处于活动状态时在线程之间迁移会话,ESENT会发出抱怨(尽管可以禁用该行为)。
几个使用ESENT的大型服务器应用程序采用了会话池方法,并且对于他们来说效果很好。
我们目前的研究显示,在page_load中实例化一个新的会话并轻松地将其放置在page_unload中可以很容易地产生600个reqs / sec,而对于一个寻找索引的简单脚本,还需要另外两个搜索。
换句话说,通过适当调整参数可能不需要会话池。
上面的例子是maxsessions设置为256.调整最小缓存大小也有助于性能。 在一台带有8 GB内存的四核测试服务器上。
如果您真的打算跨请求开放会话,这可能无法以此形式工作。
终结器将运行在一个单独的线程和关闭会话将引发错误。
大多数情况下, JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly
在Dispose()期间在JetEndSession()中JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly
。
如果你真的必须使用ESENT,也许你可以启动和管理一个专门的线程池,并打电话给他们。