В службе Windows VB.Net я в настоящее время объединяю единицы работы с:
ThreadPool.QueueUserWorkItem(operation, nextQueueID)
В каждой единице работы (или потоке, который я буду использовать для простоты понимания) он будет выполнять пару операций MSSQL, например:
Using sqlcmd As New SqlCommand("", New SqlConnection(ConnString))
With sqlcmd
.CommandType = CommandType.Text
.CommandText = "UPDATE [some table]"
.Parameters.Add("@ID", SqlDbType.Int).Value = msgID
.Connection.Open()
.ExecuteNonQuery()
.Connection.Close() 'Found connections not closed quick enough'
End With
End Using
При запуске netstat -a -o на сервере я вижу около 50 подключений к серверу SQL, сидящему на IDLE или ESTABLISHED, это кажется мне чрезмерным, особенно с учетом того, что у нас есть гораздо более крупные веб-приложения, которые обходятся 5-10 подключениями.
Строка подключения является глобальной для приложения (не изменяется) и также имеет значение Pooling=true.
Будет ли каждый из этих потоков иметь свой собственный ConnectionPool или будет один ConnectionPool для всего процесса .EXE?





Из документов MS -
«Соединения объединяются в пул для каждого процесса, для домена приложения, для каждой строки подключения, а при использовании интегрированной безопасности - для каждого удостоверения Windows»
http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
У вас есть такие ошибки, как -
Сведения об исключении: System.InvalidOperationException: время ожидания истекло. Тайм-аут период, прошедший до получения соединения из пула. Это могло произойти поскольку все соединения в пуле использовались и был достигнут максимальный размер пула.
Также сколько рабочих элементов поставлено в очередь в службе?
Нет, у меня не кончаются соединения (разве не максимальное значение по умолчанию - 25? Или было 100?)
Обычно максимум 5-10 рабочих элементов, но иногда и до 1000 (прежде чем вы спросите, я отправляю электронные письма сюда!)
Если их до 1000, значит, вы видите все связи. В конце концов диспетчер пула соединений очистит их. Вы можете очистить пул с помощью SqlConnection.ClearPool после выполнения задачи.
Если количество открытых подключений вас оскорбляет, возьмите управление в строка подключения
Примечание: MinPoolSize и MaxPoolSize.
Одна большая проблема с вашим кодом заключается в том, что вы не закрываете свое соединение, если ExecuteNonQuery генерирует исключение. Удаление SqlCommand недостаточно, вам также необходимо удалить SqlConnection при возникновении исключения, например:
Using SqlConnection connection = New SqlConnection(ConnString)
Using sqlcmd As New SqlCommand("", connection)
With sqlcmd
... etc
End With
End Using
End Using
Хотя мне в целом нравится оператор using, я обнаружил, что иногда в библиотеках .NET фактическое закрытие дескриптора не выполняется до тех пор, пока не выполняется сборка мусора. Так что, будучи олдскульным и религиозным в отношении таких вещей, я добавляю явное закрытие в конце своего оператора using. Это псевдокод, поскольку я обычно пишу на C#, а не на VB.NET, но он должен дать вам представление.
Using SqlConnection connection = New SqlConnection(ConnString)
TRY
Using sqlcmd As New SqlCommand("", connection)
With sqlcmd
... etc
End With
End Using
FINALLY
connection.Close()
End Using
Сколько рабочих элементов поставлено в очередь в службе?