LP on .NET

November 29, 2009

Thread Local Storage the Easy Way

Filed under: .NET,C#,Software Development — Larry Parker @ 10:41 pm

I recently needed to store data on a per-thread basis.  This was the first time I ever needed to do that and it was a bit of a mind shift for me.   Normally when I used threads I would share data across threads – not isolate data within a thread.

The situation was in a WCF server application where I needed to make the user id associated with the service call available to various business objects called by the service method.  One approach could have been for the service methods to pass the user id into the business objects, but that would have gotten a bit tedious.

Since each service call received by my WCF server was on a different thread (using the thread pool), storing the user id in a place specific to the current thread made the most sense.  Fortunately, this can be done in .NET by using thread local storage (TLS).

My first exposure to TLS was in a .NET book that covered this in the form of named data slots, which is a general mechanism that allows you to store any type of data specific to a thread.

So I started down the path using the static Thread.GetNamedDataSlot and Thread.SetData methods, but I noticed that MSDN recommended another mechanism for TLS – the ThreadStatic attribute.  I’m glad I caught this because the book did not cover it, and data slots are a bit sloppy to work with.

What’s so nice about the ThreadStatic attribute is that it can be applied directly to a static field, so your data is strongly typed and stands on its own (as opposed to being thrown into a general named collection as is done with data slots).  And according to MSDN, ThreadStatic is faster than data slots.

So here’s the code:

public static class SystemGlobals
{
    [ThreadStatic]
    private static Int32 _userId;

    public static Int32 UserId
    {
        get { return _userId; }
        set { _userId = value; }
    }
}

Since the private _userId variable is a static field decorated with the ThreadStatic attribute, its contents are unique per thread.  The public UserId property wraps this value and can be set by the WCF service method (which knows the user id via the service call), and can be easily accessed by any business object that needs it.  For example:

public class MyBusinessObject
{
    public void DoIt()
    {
        if (SystemGlobals.UserId == 123)
            RaiseSalary();
    }
}

This is much cleaner than passing the user id into the business object, and creates a nice isolated thread context for your business objects to run in.

I’m sure data slots have their place in some situations, but the ThreadStatic attribute is faster, safer and easier.

Hope this helps!

Advertisements

3 Comments »

  1. I was looking at the same thing recently. I know that ASP.NET has thread agility that means it is possible to start a the method execution on one thread and possibly finish on another.

    I was wondering if TLS is still valid when using IIS/ASP.NET to host services.

    Comment by Cosmin — January 25, 2010 @ 3:35 pm | Reply

  2. Hi Cosmin,

    I don’t work much in ASP.NET, but I think there’s HttpContext for thread-specific storage.

    For what I’m doing in WCF, thread agility would be bad. I know that WCF uses the thread pool, but if I get switched off to another thread, my app will break. I better check into that…

    -Larry

    Comment by Larry Parker — January 26, 2010 @ 11:40 pm | Reply

  3. Hi Larry,

    What I am trying to achieve is having the same class SystemGlobals(I call it AmbientContext) everywhere regardless of the layer I’m in(wcf service or client(could be silverlight/mvc controller/other wcf service)).

    One other way to do this without TLS is to extend the OperationContext using an IExtension and have your SystemGlobals talk to the OC extension directly. I haven’t got a working sample for this yet though. Documentation is not very good.

    Comment by Cosmin — January 27, 2010 @ 8:35 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: