SQLConnection Pooling - обработка InvalidOperationExceptions - PullRequest
0 голосов
/ 06 февраля 2009

Я занимаюсь разработкой приложения для высококонкурентного CCR, в котором крайне важно, чтобы я НЕ блокировал и не отправлял спящий поток.

Я сталкиваюсь с проблемами пула SQLConnection - в частности, получаю исключения InvalidOperationException при попытке вызвать SqlConnection.Open

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

Идеальным решением для меня был бы метод периодической повторной проверки соединения на предмет доступности, который не требует привязки потока

Есть идеи?

[Обновление] Вот связанная проблема / решение, размещенное на другом форуме

Для решения требуется управляемый вручную пул соединений. Я предпочел бы иметь решение, которое является более динамичным, т.е. включается при необходимости

Ответы [ 2 ]

1 голос
/ 08 февраля 2009

Гарри, я тоже сталкивался с этим, также используя CCR. Мой опыт заключался в том, что, полностью отделив мои потоки диспетчера от блокировки на любом вводе / выводе, я мог потреблять и обрабатывать рабочие элементы гораздо быстрее, чем пул SqlConnection. Как только был достигнут максимальный лимит пула, я столкнулся с типом ошибок, которые вы видите.

Самое простое решение состоит в том, чтобы предварительно выделить несколько не объединенных в пул асинхронных объектов SqlConnection и разместить их на некотором центральном объекте Port . Затем всякий раз, когда вам нужно выполнить команду, сделайте это в итераторе примерно так:

public IEnumerator<ITask> Execute(SqlCommand someCmd)
{
    // Assume that 'connPort' has been posted with some open
    // connection objects.
    try
    {
        // Wait for a connection to become available and assign
        // it to the command.
        yield return connPort.Receive(item => someCmd.Connection = item);

        // Wait for the async command to complete.
        var iarPort = new Port<IAsyncResult>();
        var iar = someCmd.BeginExecuteNonQuery(iarPort.Post, null);
        yield return iarPort.Receive();

        // Process the response.
        var rc = someCmd.EndExecuteNonQuery(iar);
        // ...
    }
    finally
    {
        // Put the connection back in the 'connPort' pool
        // when we're done.
        if (someCmd.Connection != null)
            connPort.Post(someCmd.Connection);
    }
}

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

  1. Тайм-аут - просто сделайте начальный прием (для доступного соединения), «Выбор» с портом тайм-аута.
  2. Настройка размера пула динамически. Чтобы увеличить размер пула, просто опубликуйте новый открытый SqlConnection в 'connPort'. Чтобы уменьшить размер пула, создайте получатель для connPort, а затем закройте полученное соединение и выбросьте его.
0 голосов
/ 15 февраля 2009

Да, соединения остаются открытыми и находятся вне пула соединений. В приведенном выше примере порт - это пул.

...