C # Static Property Locking

Just looking for a code review of this code. ASP.net cache is not an option. A static list will be available on the website, which will receive more than 10 thousand page views per day, and simultaneous reading attempts are likely. When you restart the application when the list is rebuilt, I was wondering if there are any problems that I can ignore? Is blocking on a list the best practice?

public class MyClass { private static List<Entry> _listCache = null; protected static List<Entry> ListCache { get { if (_listCache == null) { _listCache = new List<Entry>(); lock (_listCache) { //Add items to the list _listCache from XML file } } return _listCache; } } //....Other methods that work with the list } 
+4
source share
4 answers

10,000 views is once every 8 seconds ... not sure if you need to worry too much ... ;-p

But repeat the code - it's too complicated, and you can still initialize it twice anyway. I would just use a static constructor for this; It will be more reliable. If you must have a complete isolated lazy load (even with other static methods for the type), there is a trick with an inner class to achieve the same:

 public class MyClass { static class InnerCache { internal static readonly IList<Entry> _listCache; static InnerCache() { List<Entry> tmp = new List<Entry>(); //Add items to the list _listCache from XML file _listCache = new ReadOnlyCollection<Entry>(tmp); } } protected static IList<Entry> ListCache { get {return InnerCache._listCache;} } } 

I would also be worried about the possibility of someone mutating the list — perhaps they would want to use the list as read-only!

+12
source

A static constructor might be the best choice here. The static constructor blocks all threads that depend on it during its launch, and it will be launched only once. Since you have the code here, blocking doesn't actually do anything, and there are many ways that can happen to bad things, including initializing multiple lists from XML at the same time. In fact, one thread can create a new list, then block and load another list, and then return the third list, depending on when the thread switching occurs.

+2
source

There really is no reason that this will not work for you. However, if you want to do this like your sample code, you want to block before you check if _listCache is null. Therefore, to lock you will need a separate monitor. Something like that:

 public class MyClass { private static object _listCacheMonitor = new object(); private static List<Entry> _listCache = null; protected static List<Entry> ListCache { get { lock (_listCacheMonitor) { if (_listCache == null) { _listCache = new List<Entry>(); //Add items to the list _listCache from XML file } } return _listCache; } } //....Other methods that work with the list } 
+2
source

Multiple threads can initialize _listCache. Depending on the optimization of code generation and optimization of runtime execution, this can lead to blocking of several threads and updating of various objects. In addition, you cannot expand the list as a property that allows someone to add / remove an object without blocking.

You are better off using an immutable list that several readers can safely parse in read-only mode. Alternatively, you can use read / write locks, but things get pretty hairy between the initialization control and the rw access control.

+1
source

All Articles