The way these things are normally done is with threadpools. See System.Threading.ThreadPool and read MSDN: How to: Use a Thread Pool
Also, the modern approach to sharing data in multithreaded environments is to avoid using locks and to use message-passing instead. This results in systems that are testable, and that once they are known to work, they tend to keep working without nasty surprises due to rare timing issues.
Note: invoking listOfConnectors.Remove( x ); within a foreach( var x in listOfConnectors ) will throw a concurrent modification'collection was modified' exception.