I think I’ve developed a cargo-cult programming habit:
Whenever I need to make a class threadsafe, such as a class that has a Dictionary or List (that is entirely encapsulated: never accessed directly and modified only by member methods of my class) I create two objects, like so:
public static class Recorder {
private static readonly Object _devicesLock = new Object();
private static readonly Dictionary<String,DeviceRecordings> _devices;
static Recorder() {
_devices = new Dictionary<String,DeviceRecordings>();
WaveInCapabilities[] devices = AudioManager.GetInDevices();
foreach(WaveInCapabilities device in devices) {
_devices.Add( device.ProductName, new DeviceRecordings( device.ProductName ) );
}
}//cctor
// For now, only support a single device.
public static DeviceRecordings GetRecordings(String deviceName) {
lock( _devicesLock ) {
if( !_devices.ContainsKey( deviceName ) ) {
return null;
}
return _devices[ deviceName ];
}
}//GetRecordings
}//class
In this case, I wrap all operations on _devices within a lock( _devicesLock ) { block. I’m beginning to wonder if this is necessary. Why don’t I just lock on the dictionary directly?
In your use case, locking the dictionary will be fine, since it is private. You still need to carefully design your class to prevent deadlocks.
If the dictionary is the only shared resource that needs thread safety and other parts of your code are thread-safe, I’d recommend using the ConcurrentDictionary instead of locking.