2011-04-06 15 views
15

Son çözüm:

Bağlantı, bağlantı havuzuna eklenmiştir. Ben de kapattım ama yine de fiziksel olarak açık kaldı. ConnectionString Parametresi ile "Pooling = false" veya MySqlConnection.ClearPool (bağlantı) ve MySqlConnection.ClearAllPools statik yöntemleri ile sorun önlenebilir. Sorunun, uygulamayı kapattığımda bağlantının hala canlı olduğunu unutmayın. Onu kapatmamıza rağmen. Bu yüzden ya hiç havuz kurmayı kullanmıyorum ya da bağlantıyı kapatmadan önce özel havuzu temizliyorum ve problem çözüldü. Vakamda en iyi çözümün ne olduğunu bulmak için zamanımı alacağım.C# içindeki MySQLConnection kullanımı düzgün kapanmıyor

Yanıtlayan herkese teşekkürler! C# kavramlarını daha iyi anlamama yardımcı oldu ve yararlı girdiden çok şey öğrendim. :)

===

Orjinal Sorun:

Bir süredir aramalara ve benim sorununa çözüm bulamadık: C# için yeni ve yazmayı deneyin MySql Bağlantılarını daha kolay hale getirmek için bir sınıf. Sorunum, bir bağlantı açıp kapattıktan sonra. Veritabanında hala açık ve iptal edildi.

'using' ifadesini kullanıyorum 'tabiki, ancak bağlantı hala açık ve programdan çıktıktan sonra iptal ediliyor.

İşte benim kod gibi görünüyor:

using (DatabaseManager db = new DatabaseManager()) 
{ 
using (MySqlDataReader result = db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC")) 
{ 
    foreach (MySqlDataReader result in db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC")) 
    { 
     //Do stuff here 
    } 
} 
} 

sınıf Veritabanı yöneticisi bağlantısı açar ve bertaraf zaman kapatır:

public DatabaseManager() 
{ 
    this.connectionString = new MySqlConnectionStringBuilder("Server=localhost;Database=businessplan;Uid=root;"); 
    connect(); 
} 
private bool connect() 
{ 
    bool returnValue = true; 
    connection = new MySqlConnection(connectionString.GetConnectionString(false)); 
    connection.Open(); 
} 

public void Dispose() 
{ 
    Dispose(true); 
} 

public void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     if (connection.State == System.Data.ConnectionState.Open) 
     { 
      connection.Close(); 
      connection.Dispose(); 
     } 
    } 
    //GC.SuppressFinalize(this);//Updated 
} 
//Updated 
//~DatabaseManager() 
//{ 
// Dispose(false); 
//} 

Yani, debugger ve Dispose bunu kontrol () -method çağrılır ve doğru şekilde yürütülür. Neyi eksik? Yanlış yaptığım ya da yanlış anladığım bir şey mi var?

Herhangi bir yardım için teşekkür ederiz!

Selamlar, Simon

PS: Her ihtimale DataReader() - yöntem (Güncelleme sürümü):

public IEnumerable<IDataReader> DataReader(String query) 
    { 
     using (MySqlCommand com = new MySqlCommand()) 
     { 
      com.Connection = connection; 
      com.CommandText = query; 
      using (MySqlDataReader result = com.ExecuteReader(System.Data.CommandBehavior.CloseConnection)) 
      { 
       while (result.Read()) 
       { 
        yield return (IDataReader)result; 
       } 
      } 
     } 
    } 

Tamam, verim dönüşü kullanmaya çalıştı:

DataReader yöntemini değiştirdim:

public IEnumerable<IDataReader> DataReader(String query) 
    { 
     using (MySqlCommand com = new MySqlCommand()) 
     { 
      com.Connection = connection; 
      com.CommandText = query; 
      using (MySqlDataReader result = com.ExecuteReader()) 
      { 
       while (result.Read()) 
       { 
        yield return (IDataReader)result; 
       } 
      } 
     } 
    } 

Verileri alabildiğim şekilde çalışır, ancak yine de aynı sorunla karşılaşıyorum: Bağlantı düzgün şekilde kapatılmadı. :(

+0

Yönetilmeyen kaynaklarınız olmadığından, bir sonlandırıcıya ihtiyacınız yoktur. – SLaks

+0

Bu doğru. Ama şu an canım yanmıyor, değil mi? Yanılıyorsam beni düzeltin. Ana amaç, kullanılmayan bağlantıları artık gerekli olmadıkça kapatmaktır. Bu örüntü, bu hedefe ulaşmanın kolay bir yolu gibi görünüyordu. Web'deki birçok örnekte gösterildiği gibi uyguladım. Sonunda gereksiz koddan kurtulmak için değiştireceğim. – Skalli

+1

Bu bir performans isabeti, ancak aksi halde, hayır. – SLaks

cevap

15

Im emin!

Düzenleme: Reader, Command ve Connection nesnelerini attığınızdan emin olun!

Düzenleme: gittiğinde ConnectionString Parametre "havuzu oluşturma = false" veya statik yöntemler MySqlConnection.ClearPool (bağlantı) ve MySQL Docs göre MySqlConnection.ClearAllPools()

+0

Şu anda bunlar için kullanım yönergesini kullanıyorum. Bkz. [Link] (http://stackoverflow.com/questions/5567097/using-mysqlconnection-in-c-does-not-close-properly/5567722#5567722). Hala işe yaramıyor. – Skalli

+1

Bu gönderi aslında aradığım yanıtı aldı, ancak bunu fark etmedim, çünkü Bağlantı Havuzu'nun nasıl çalıştığını bilmiyordum. Şimdi anlıyorum ve sorunu çözdüm. Yani, teşekkürler @Petoj. – Skalli

+0

no problem yardımcı olmaktan mutluluk! – Peter

5

Komutu ve DataReader'ı using ifadelerinde de kaydetmeniz gerekir.

+1

Peki, ama nasıl? MySqlDataReader'ı bir use-block'a sarsam, yalnızca yerel olarak kullanılabilir. DataReader yöntemi, bir kullanarak bloğa döndürür. Bunu kullanarak, MySqlDataReader-Object'i kullanım bloğunun sonuna atacağımı varsayalım: using (MySqlDataReader result = db.DataReader (...) – Skalli

+0

O, MySqlDataReader'ı döndürdüğü için sarmayı başaramaz - MySqlCommon'u bitirinceye kadar MySqlCommand'ı elden çıkarmanız gerektiğini düşünmüyorum.Onu bir kapanmaya çevirmek için bir getiri getirisine bakmalı. –

+0

Haklısınız. Okuyucunun Disposed'ı ile başa çıkabilirsin: 'reader.Disposed + = delege {com.Dispose();}' – SLaks

-1

böyle bir şey kullanarak göz at: mysqlconnection ama parçası Bağlantı havuzu kullanan ve bunun yerine bağlantı havuzunda koyar yakın çağırdığınızda kapanmaz SQL Server sayaç hakkında

private static IEnumerable<IDataRecord> SqlRetrieve(
    string ConnectionString, 
    string StoredProcName, 
    Action<SqlCommand> AddParameters) 
{ 
    using (var cn = new SqlConnection(ConnectionString)) 
    using (var cmd = new SqlCommand(StoredProcName, cn)) 
    { 
     cn.Open(); 
     cmd.CommandType = CommandType.StoredProcedure; 

     if (AddParameters != null) 
     { 
      AddParameters(cmd); 
     } 

     using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
     { 
      while (rdr.Read()) 
       yield return rdr; 
     } 
    } 
} 
+0

Ben ona bir göz atacağım Oldukça ilginç görünüyor.Önce getiri geri dönüşü görmedim. – Skalli

+0

@ user694856 http://stackoverflow.com/ soruları/850065/return-datareader-datalayer-in-using-statement –

+0

Kullanmayı denedim, mesajımı gör: [link] (http://stackoverflow.com/questions/5567097/using-mysqlconnection-in- c-yok-yakın-düzgün/5567722 # 5567722) – Skalli

2

ile çözüldü, MySQLConnection kapalı değil kapsam dışında. Bu nedenle onu bir kullanımda kullanmamalısınız.

Alıntı ... "MySqlConnection kapsam dışında giderse, kapatılmamış. Bu nedenle, açıkça MySqlConnection.Close veya MySqlConnection.Dispose arayarak bağlantıyı kapatmak gerekir."

+2

Kullanımı Nesne kapsam dışına çıktığında aramayı kapatın ve atın. Bir try catch bloğu kullanmakla aynıdır ve onu son blokta kapatın ve atın. – Skalli

+1

@Skalli doğru. Bir kullanım ifadesinin kapsamını bırakmak, bir dil anlamında kapsamı kaybetmekle aynı şey değildir. Bir kullanma ifadesi Kapat'ı arayacak. –