Thursday, October 16, 2008

When Hashtable is better than Dictionary

We all know Hashtable class - it exists in .NET from the very beginning. .NET 2.0 has brought a generic replacement to it: Dictionary. So we usually prefer using it rather than Hashtable. But it isn't well known Hashtable has a very nice feature related to concurrent usage, which Dictionary does not have (at least by documentation):

- Hashtable supports single writer and multiple readers concurrent access policy
- But Dictionary - standard single writer or multiple readers concurrent access policy

This means usage of Hashtable is perfect e.g. in concurrent caching scenarios: only write operations on it require locking to ensure thread safety, but in case with Dictionary both read and write operations require locking.

The official "approval" of this fact is here.

And a fly in the ointment:
- It's difficult to find out if this was fully correct for .NET 2.0, since this fact was mentioned only recently. The issue report related to this is here.
- This is not completely true: here is the report.

Possible workarounds:
- Never clear or remove items from Hashtable at all. In many cases this is ok, e.g. when you cache something for a lifetime of the cache or the whole application. An example is caching of Reflection.Emit results or any other code loaded into AppDomain: you anyway can't unload the code, so there is no reason to clean up any references to it from caches.
- Implement item removal by dropping the old Hashtable and copying its content (without the item to remove) to a new one. Or implement a wrapper doing the same using two Hashtables (one contains just added keys and values, and andother one just removed keys) and periodically doing the garbage collection be re-creating both of them as described above. But actually the cost of looking into two Hashtables must be close to the cost of locking.

In any case, this feature is very nice even with all the mentioned problems. We utilize this feature of Hashtable e.g. in our ThreadSafeDictionary class.