我正在考虑一个ASP.NET应用程序,它使用ESENT来实现持久性。
在这一点上,这只是我的爱好项目,所以需求非常灵活。不过,我希望它能在Windows7、Windows2008和2008IIS3.5及更高版本的R2上运行,并使用默认的.NET设置。
在ESENT中,大多数操作都需要打开一个会话对象。文档说:“会话跟踪它在哪个线程上使用,如果在具有打开的事务的多个线程上使用它,它将抛出错误。”API文档提到的是本机线程,而不是托管线程。
我假设打开会话操作的开销相对较大,这就是为什么我不想为每个HTTP请求打开/关闭会话。
最后,这是我的问题。
在执行C#代码的每个本机线程上,如何在asp.net中只初始化/反初始化一次?
下面发布的代码可以为我工作吗?
在使用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();
}
}发布于 2010-06-30 04:03:40
一个不错的方法是创建一个会话池,让线程从池中抓取一个会话,然后在完成后返回该会话。会话可以由不同的线程使用,但是如果在事务处于活动状态时在线程之间迁移会话,ESENT将会报错(虽然可以禁用该行为)。
几个使用ESENT的大型服务器应用程序已经采用了会话池方法,并且这种方法对它们很有效。
发布于 2010-11-05 03:47:41
我们目前的研究表明,在page_load中实例化一个新会话并将其处理在page_unload中可以轻松地产生600reqs/sec的wcat,这是一个简单的脚本,它在索引上进行查找,并对每个返回的行执行另外两次查找。
换句话说,通过对esent参数进行适当的调优,可能不需要会话池。
上面的示例是将最大会话数设置为256。调整最小缓存大小也有助于提高性能。在具有8 gb内存的四核测试服务器上。
发布于 2010-06-28 03:17:24
如果你真的想让会话在不同的请求之间保持打开状态,这在这种形式下可能行不通。
终结器将在单独的线程上运行,关闭会话将抛出错误。
在Dispose()过程中,很可能是JetEndSession()中的JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly。
如果你真的必须使用ESENT,也许你可以手动启动和管理一个专用的线程池,并对来往于它们的调用进行编组。
https://stackoverflow.com/questions/3127435
复制相似问题