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