views:

56

answers:

3

I'm thinking over an ASP.NET application that uses ESENT for persistance.

At this point this is just my hobby project, so the requirements are very flexible. However I'd like it to work on Windows 7, Windows 2008, and 2008 R2, with .NET 3.5 and higher, and default IIS settings.

In ESENT, most operations require you to open a session object. The documentation says: "A session tracks which thread it was used on, and it will throw an error if used on multiple threads with an open transaction." The API documentation mentions the native threads, not managed threads.

I assume the open session operation is relatively expensive, that's why I don't want to open/close session for every HTTP request.

Here're my questions, finally.

How in asp.net do I initialize / deinitialize something exactly once, on every native thread that executes my C# code?

Will the code like posted below work for me?

Is there something bad I don't know in keeping the asp.net managed thread constantly pinned to the native thread with BeginThreadAffinity method? Wont my sessions leak after the IIS is under the load for a month without a single reboot?

Thanks in advance!

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();
    }
}
A: 

This will probably not work in this form if you really intend to leave the session open across requests.
The finalizer will run on a separate thread and closing the session will throw an error.
Most probably JET_errSessionInUse - session was in use on another thread, or the session was not set or reset properly in JetEndSession() during Dispose().

If you really must use ESENT, maybe you can fire up and manage a dedicated pool of threads by hand and marshal calls to/from them.

andras
+1  A: 

One good approach is to create a pool of sessions and have threads grab a session from the pool and then return the session when done. A session can be used by different threads, but ESENT will complain if you migrate a session between threads while a transaction is active (it is possible to disable that behaviour though).

Several large server apps that use ESENT have taken the session pool approach and it works well for them.

Laurion Burchall
I'll try to implement that approach as soon as I'll have time for that.Work is first, hobby projects are next :-)BTW I don't think this is gonna be my last question here tagged "C# esent".I really liked your technology, and I'm successfully using it in my commercial project.Thank you for your support!
Soonts