1

我正在考虑使用 ESENT 进行持久性的 ASP.NET 应用程序。

目前这只是我的爱好项目,所以要求非常灵活。但是,我希望它可以在具有 .NET 3.5 及更高版本以及默认 IIS 设置的 Windows 7、Windows 2008 和 2008 R2 上运行。

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

我假设打开会话操作相对昂贵,这就是为什么我不想为每个 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();
    }
}
4

3 回答 3

3

一种好的方法是创建一个会话池,让线程从池中获取一个会话,然后在完成后返回该会话。一个会话可以被不同的线程使用,但是如果您在事务处于活动状态时在线程之间迁移会话,ESENT 会报错(尽管可以禁用该行为)。

几个使用 ESENT 的大型服务器应用程序采用了会话​​池方法,并且对它们很有效。

于 2010-06-29T20:03:39.527 回答
1

我们目前的研究表明,在 page_load 中实例化一个新会话并在 page_unload 中处理它很容易产生 600 reqs/sec 与 wcat 一个简单的脚本在索引上搜索,并为每个返回的行执行另外两个搜索。

换句话说,通过适当调整 esent 参数,可能不需要会话池。

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

于 2010-11-04T19:47:41.190 回答
0

如果您真的打算让会话在请求之间保持打开状态,这可能不适用于这种形式。
终结器将在单独的线程上运行,关闭会话将引发错误。
最有可能 JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly在 Dispose() 期间在JetEndSession()中。

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

于 2010-06-27T19:17:23.900 回答