Если я правильно понимаю, что вы делаете правильно, то это выглядит очень сомнительно:
static public SqlConnection conn;
static public SqlConnection GetConnected() {
try
{
String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
conn = new SqlConnection(strConnectionString);
}
}
static public void CloseConnection() {
// Libération de la connexion si elle existe
if (IsConnected) conn.Close();
}
Вы работаете со статической переменной соединения, что означает, что когда вы закрываете ее, вы закрываете последнюю открытую переменную.
В многопользовательском сценарии это может произойти:
- Пользователь A: Создать соединение (и вернуть соединение 1)
- Пользователь A: выполнить запрос (запускается для соединения 1)
- Пользователь B: создать соединение (и вернуть соединение 2)
- Пользователь A: закрыть соединение (последнее открытое было 2, значит, закрыто)
- Пользователь B: выполнить запрос (запускается для соединения 2, оно уже закрыто ... взрыв)
Кроме того, вам, вероятно, следует пересмотреть вопрос о том, чтобы ваше соединение являлось общедоступной переменной-членом:
static public SqlConnection conn;
Обычно это считается плохой практикой и может привести к неожиданным / трудным отслеживанию ошибок в будущем, если какой-либо код вне вашего класса начнет возиться с его внутренними переменными.
EDIT:
Наиболее очевидным решением, по-видимому, было бы прекращение статического соединения. Ваш клиентский код может выглядеть примерно так:
try{
// use using block around connection, calls dispose automatically when
// block ends...
using(var connectionWrapper = new Connexion_D()) {
var connectedConnection = connectionWrapper.GetConnected();
// do CRUD
}
}
catch{
// catching Error, avoid yellow page aspx
// Really you should probably be doing something with the exception (logging?)
// particularly since you go to the effort of throwing it from your Connection_D
// class.
}
с вашим кодом класса, похожим на:
/* Implement IDisposable to cleanup connection */
public class Connexion_D : IDisposable
{
public SqlConnection conn;
public SqlConnection GetConnected()
{
try
{
String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
conn = new SqlConnection(strConnectionString);
}
catch (Exception excThrown)
{
conn = null;
throw new Exception(excThrown.InnerException.Message, excThrown);
}
// Ouverture et restitution de la connexion en cours
if (conn.State == ConnectionState.Closed) conn.Open();
return conn;
}
public Boolean IsConnected
{
get { return (conn != null) && (conn.State != ConnectionState.Closed) && (conn.State != ConnectionState.Broken); }
}
public void CloseConnection()
{
// Libération de la connexion si elle existe
if (IsConnected) {
conn.Close();
conn = null;
}
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
// Close connection
}
}
См. this для получения дополнительной информации о реализации IDisposable.