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

November 28, 2009

Unit Testing Exceptions

Filed under: .NET,C#,Microsoft,Software Development,Visual Studio — Larry Parker @ 10:23 pm

Up until recently,  I had been following a pattern in my unit tests of catching expected exceptions that is similar to the following:

[TestMethod()]
public void AddTaskTest()
{
    Schedule target = new Schedule("* * * * *", "Every minute");
    ScheduledTask scheduledTask = null;

    Boolean isCaught = false;
    try
    {
        target.AddTask(scheduledTask);
    }
    catch (ArgumentNullException) { isCaught = true; }
    Assert.IsTrue(isCaught);
}

This works, but is a bit of a pain to write every time you want to check that an exception gets thrown by the method being tested.

I found a better approach at this blog post by Pedro Silva of Microsoft.

I modified it slightly to take a generic type parameter instead of passing in the type as a formal parameter (a little easier in my opinion).

Now the unit test looks like this:

[TestMethod()]
public void AddTaskTest()
{
    Schedule target = new Schedule("* * * * *", "Every minute");
    ScheduledTask scheduledTask = null;

    UnitTestHelper.TestException<ArgumentNullException>(() =>
        target.AddTask(scheduledTask));
}

Much simpler – especially when you’re testing for lots of exceptions!

I’m using a lambda expression in this example, but you can also use an anonymous delegate as in the blog.  I just think lambdas are more succint, but either will do.

Here’s the code with my tweaks (comments removed for brevity – please check the original blog post for more info).

public static class UnitTestHelper
{
    static public void TestException<T>(Action action)
    {
        try
        {
            action();
            Assert.Fail("Test should have thrown exception " +
                typeof(T).Name + ".");
        }
        catch (AssertFailedException) { throw; }
        catch (Exception e)
        {
            Assert.IsInstanceOfType(e, typeof(T),
                "Exception is not of the expected type.", typeof(T).Name);
        }
    }
}

Create a free website or blog at WordPress.com.