I’m currently using a Hashtable wrapped as a Hashtable.Synchronized as a simple cache in a library that could be used by a multi-threaded environment (such as asp.net) – is this a suitable use for this collection? I understand that there are more suitable constructs available in .Net 4.0, but I’m stuck with .Net 3.5.
If it makes any difference, this cache is read from frequently, and is written to very infrequently (but needs to remain threadsafe).
Basic usage is something along the lines of:
Private Shared ReadOnly ExpressionCache As Hashtable = Hashtable.Synchronized(New Hashtable())
..snip...
If Not ExpressionCache.ContainsKey(myKey) Then
ExpressionCache(myKey) = myExpensiveOperationToInit()
End If
Return ExpressionCache(myKey)
..snip..
Am I doing something potentially dangerous here, or is this an acceptable use case?
Actually,
Hashtable(unlikeDictionary<,>) already has very good threading semantics for use as a cache: it is thread-safe for readers (but requires locking for writers) – from MSDN:(it also mentions
.Synchronizedfor supporting multiple writers, but frankly taking control of this ourselves usually gives much better results)However, to avoid phantom reads, you shouldn’t use separate “contains” / “get” operations; standard use might be (using C# for the example):
key points:
Add, in the set (then you don’t need to check “contains” first)The
.Synchronizedwrapper is actually of remarkably little value in most common threading scenarios.