1) Yes
2) This is a dead end
3) The parts of your code that you want to block are implementation details of your class. Detecting a lock object using lock(this) or lock(this.GetType()) causes problems, because now external code can lock the same object and lock your code inadvertently or maliciously. The lock object must be closed.
4) It’s not entirely clear what you mean, of course, you don’t want to expose the Hashtable directly. Just save it as a private field of the class, encapsulating it.
However, the likelihood that you can safely expose your class to client code using threads decreases very quickly with the number of public methods and properties that you expose. You will quickly get to the point where only client code can correctly lock the lock. The fine-grained locking creates many opportunities for the streaming race when client code holds onto property values. Say the return value of the Count property. By the time the value is used, as in the for loop, the Count property could have been changed. Only the most thorough design can escape these traps, a serious headache.
In addition, fine-grained locking is very inefficient, as it inevitably occurs in most of the internal parts of your code. Locks are not so expensive, about 100 cpu cycles, but they add up quickly. Especially wasted if the class object is not actually used in multiple threads.
You then have no option, but declare your class stream unsafe, and client code should use it in a thread-safe manner. Also, the main reason many .NET classes are not thread safe. This is the biggest reason that threads are so hard to get right, the programmer, the least likely to do it right, is responsible for doing the most difficult thing.
Hans passant
source share