Earlier this week, I posted a reminder that static methods don't always require locking. However, I also wanted to emphasize to exercise caution when selecting the object that will be used for a lock. For years, there have been many examples that use the containing type for the lock object, but this is not really a good idea.
Here's an example of the wrong way:
public class MyClass
{
private static int _counter = 0;
// Don't do this!
public static int StatefulAdd(int value1, int value2)
{
lock (typeof(MyClass))
{
_counter++;
}
return value1 + value2;
}
}
There have been numerous publications and blog articles written with locking examples that do something similar. However, this is not a recommended best practice, and Microsoft has been attempting to modify their documentation to reflect the preferred approach. Before I get into the recommended approach, let me clarify what's wrong with the other solution.
First, the typeof operator is relatively slow, at least when compared to accessing a variable within the class. Second, typeof returns a Type object, which is a publicly accessible object. As such, any other class could choose to lock on the same object, which opens up the potential for deadlock scenarios.
So, what is the recommended best practice? Rather than using a Type object or some other publicly accessible object, it is recommended to use a private static member variable. This ensures that only the implementation within the containing type has access to the lock object.
Here's an example of the right way:
public class MyClass
{
private static int _counter = 0;
private static object _lockObject = new object();
// Do this!
public static int StatefulAdd(int value1, int value2)
{
lock (_lockObject)
{
_counter++;
}
return value1 + value2;
}
}
For a more insight into possible problems with the typeof approach, there are a couple of articles that I recommend reading. Here is a link to an MSDN article from 2003. Here is a link to a blog post from Joe Duffy aka Threading Master. Even though the MSDN article was dated back in 2003, I have still seen some articles as recently as 2007 that still contain examples of using typeof. As they say, some habits die hard.