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

时间:2010-06-27 13:14:35

标签: c# asp.net windows multithreading esent

我正在考虑使用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();
    }
}

3 个答案:

答案 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,也许你可以手动启动和管理一个专用的线程池,并调用它们的来电/来自它们。