If I understand it correctly, HashTable and Dictionary are both not thread safe by default.
In order to make HashTable thread safe it is needed to use Hashtable.Synchronized(Hashtable) Method.
In order to make Dictionary thread safe it is needed to use ConcurrentDictionary or implement your own lock logic.
is my understanding correct?
You are correct, HashTable and Dictionary are not thread safe. HashTable can be made (sort of) thread safe using the HashTable.Synchronized function. This creates a wrapper around the HashTable allowing only one writer and multiple readers to access HashTable. But.
The wrapper around the HashTable is not fully thread safe, one could iterate the collection while another thread could concurrently still change the collection resulting in an exception.
Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
Depending on the situation I would pick a collection from the System.Collections.Concurrent namespace. Which is best described here: https://learn.microsoft.com/en-us/dotnet/standard/collections/thread-safe/
Bear in mind though that these collections are not the fastest - if speed is important I would recommend tailoring one to your specific needs.