Причина, по которой вы получаете исключение, заключается в том, что, когда у вас нет доступных подключений, вы создаете новое подключение и возвращаете его, не вызывая для него Monitor.Enter ().Это означает, что вы будете использовать нерекурсивный SyncLock для ссылки на этот объект, снимите эту блокировку и затем попытаетесь вызвать Monitor.Exit () для дополнительной блокировки, которую вы никогда не брали в первую очередь.
ВыТакже есть потенциальное состояние гонки, в зависимости от способа добавления соединений в пул.Другой поток вполне может взять блокировку только что созданного вами соединения (через вызов Monitor.TryEnter ()), прежде чем вы сделаете его блоком SyncLock, чтобы получить его самостоятельно.Если вы закрываете соединение перед его возвратом в пул (что является хорошей идеей), то когда ваш поток создания действительно начнет его использовать, у вас будет плохое состояние соединения.
Я бына самом деле предлагаю вам не пытаться написать свой собственный пул соединений.В вашем текущем коде нет ничего, что бы указывало на то, что вы не можете просто использовать System.Data.SqlClient.SqlConnection, который уже обрабатывает пул соединений для вас.