C # Вопрос о безопасности потоков - PullRequest
2 голосов
/ 13 марта 2009

Я использую пул потоков для выполнения тяжелой обработки, а также биты sql. В настоящее время я открываю соединения SQL, когда они мне нужны, запускаю запрос и затем закрываю их. Это отлично работает. Приложение работает без проблем. Чем больше работы выполняется этим приложением, тем больше потоков. Больше потоков означает больше открытия / закрытия соединений SQL. В SQL 2005 это фактически забивает сервер. Мой тестовый сервер выполняет около 175 транзакций в секунду. Приблизительно 150 из них выполняются в базе данных master и являются «ValidateSQLLogin».

Я собираюсь изменить приложение так, чтобы у каждого потока было свое собственное соединение, а затем это соединение передавалось по потоку.

Итак, мой вопрос:

Если объект соединения SQL создается локально в потоке и затем передается по ссылке в статическую функцию другого класса, это будет небезопасно?

void ThreadA()
{
    SqlConnection a = new SqlConnection(....);
    MyStaticClass.DoStuff(ref a);
}

void ThreadB()
{
    SqlConnection b = new SqlConnection(....);
    MyStaticClass.DoStuff(ref b);
}

static void MyStaticClass.DoStuff(ref SqlConnection sql)
{
    // Do stuff with sql
}

Сначала я думал, что это будет небезопасно, поскольку все 10 потоков могут одновременно вызывать одну и ту же статическую функцию, каждый из которых передает свой собственный объект соединения.

Ранее статические функции открывали свои собственные соединения и закрывали их, когда они были сделаны.

Если это небезопасно, какой лучший способ обойти это? Мне нужно попытаться минимизировать открытие / закрытие соединений Sql.

Спасибо

Gareth

Ответы [ 6 ]

5 голосов
/ 13 марта 2009

Параметр для статической функции не совпадает со статическим полем. Каждое выполнение статической функции будет использовать разные копии соединения. Вам даже не нужно иметь параметр в качестве ссылки (вам нужны ссылочные параметры, только если вы хотите изменить их).

2 голосов
/ 13 марта 2009

Каждый поток имеет свой собственный стек, а параметры и локальные переменные хранятся в стеке, поэтому нет проблем с несколькими потоками, вызывающими один и тот же статический метод. Каждый вызов метода имеет свои параметры и локальные переменные.

Нет никакой причины передавать SqlConnection по ссылке на метод.

0 голосов
/ 13 марта 2009

Попробуйте следующее:

Вы можете использовать оператор lock , чтобы запретить другим потокам входить в блок кода, где вы используете это соединение, другие потоки автоматически ждут, пока предыдущий поток завершится, и затем входят в этот сегмент. Просто убедитесь, что объект, который вы блокируете, является частным для вашего статического класса.

0 голосов
/ 13 марта 2009

Если у вас есть такая нагрузка транзакций, я бы порекомендовал сохранить одно статическое соединение, которое остается открытым, пока у вас есть эти транзакции, и когда нагрузка сильно уменьшается или равна нулю, она автоматически закрывается, а при новых запросах открывается снова .

0 голосов
/ 13 марта 2009

В .Net все статические элементы являются поточно-ориентированными.

0 голосов
/ 13 марта 2009

Как говорили другие, вызов статического метода из нескольких потоков сам по себе не представляет опасности. Однако, если статический метод изменяет / обращается к статическим полям * вместо того, чтобы просто работать с параметрами, которые вы передаете, вы должны будете сделать его поточно-ориентированным.

  • исключение: некоторые типы значений используют атомарные операции для доступа / записи и неявно поточно-ориентированы для этих операций. Однако условия гонки могут по-прежнему возникать в логике, которая извлекает и обновляет их.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...