Classe .NET SqlConnection, pool de conexão e lógica de reconexão

Temos algum código de cliente que está usando a classe SqlConnection no .NET para conversar com um banco de dados SQLServer. Está intermitentemente falhando com este erro:

"ExecuteReader requer uma conexão aberta e disponível. O estado atual da conexão é fechado"

A solução "temporária" é reiniciar o processo, após o que tudo funciona - no entanto, isso é obviamente insatisfatório.

O código está mantendo um cache de instâncias do SqlConnection, uma para cada banco de dados.

Gostaríamos de reescrever o código, mas antes disso eu preciso saber algumas coisas:

Minha primeira pergunta é: é ineficiente conectar e desconectar objetos SqlConnection repetidamente ou a biblioteca subjacente executa o pool de conexões em nosso nome?

// Is this bad/inefficient?
for(many-times)
{
    using(SQLConnection conn = new SQLConnection(connectionString))
    {
        // do stuff with conn
    }
}

Porque o nosso código nãonão fazer o acima, o que parece ser a causa provável do problema é que algo acontece com o banco de dados SQLServer subjacente durante o "tempo de vida" da conexão que faz com que a conexão seja fechada ...

Se descobrir que vale a pena "armazenar em cache" objetos SqlConnection, qual é a maneira recomendada de lidar com todos os erros que poderiam ser resolvidos simplesmente "reconectando" ao banco de dados. Estou falando de cenários como:

O banco de dados é colocado off-line e colocado de volta online, mas o processo do cliente não tinha transações abertas enquanto isso aconteciaO banco de dados foi "desconectado" e, em seguida, "reconectado"

Percebo que existe uma propriedade "State" em SqlConnection ... existe uma maneira apropriada de consultar isso?

Finalmente, tenho uma instância de teste SQLServer configurada com direitos de acesso total: como posso reproduzir o erro exato "ExecuteReader requer uma conexão aberta e disponível. O estado atual da conexão é fechado"

questionAnswers(3)

yourAnswerToTheQuestion