2011-06-13 13 views
5

ben üzerinde çalışıyorum uygulamaların birinde DB bağlanmak için kod incelerken C# bağlanmış ve ben döngü endişeler ise buiyi yolu şeyler

if (_dbConnection == null) 
    _dbConnection = GetConnection(); 

while (_dbConnection.State == ConnectionState.Connecting) 
{ 
    //Do Nothing until things are connected. 
} 

if (_dbConnection.State != ConnectionState.Open) 
    _dbConnection.Open(); 

var command = GetCommand(commandType); 
command.Connection = _dbConnection; 
return command; 

gördü kadar ben mi. İşler birbirine bağlanana kadar hiçbir şey yapmanın daha iyi bir yolu var mı?

DÜZENLEME: Bağlantı olarak kazanılmış olan

bu, yapılacak en iyi şey, bağlanmaya çalışırken başladığından beri zaman süresi geçtikten hesaplamak için bir web uygulamasıdır edilir düşünüldüğünde

private static IDbConnection GetConnection() 
{ 
    return new SqlConnection(ConfigurationManager.ConnectionStrings["CoonectionStringName"].ConnectionString); 
} 
+2

Ne tür bir bağlantı? System.Data.SqlClient.SqlConnection? –

+1

Bir zaman aşımı yanı sıra zaman döngüsü bir gecikme/bekletme deyim koyarak bu yüzden CPU zamanı boşa harcamıyorsunuz – Earlz

+0

Bağlantı sınıfı System.Data.IDbConnection – Omar

cevap

5

, diğer cevaplar kilit noktayı kaçırmak gibi görünüyor; Arkaplan işleminin biraz iş yapmasına izin vermelisin. Bir süre döngü boyunca çalkalamak çok üretken değil, ama Windows büyük olasılıkla beklemekte olan, muhtemelen ne yapıyor, uygulamanın ana iş parçacığı düşünecek ve arka plan operasyonundan önce yüzlerce veya binlerce kez dönecek CPU saatinin tek bir saatini alır.

Bunu önlemek için, işlemcinin CPU süresini bekleyen tüm diğer iş parçacıklarını döndürmesini ve bittiğinde geri gelmesini söylemek için Thread.Yield() deyimini kullanın. Bu, bilgisayarın temelde boş bir döngüde dönmesi için tekelleştirilmesi yerine arka plan işlemini beklerken biraz işin yapılmasına olanak tanır. Bu çok basit;

var startTime = DateTime.Now; 
var endTime = DateTime.Now.AddSeconds(5); 
var timeOut = false; 

while (_dbConnection.State == ConnectionState.Connecting) 
{ 
    if (DateTime.Now.CompareTo(endTime) >= 0) 
    { 
     timeOut = true; 
     break; 
    } 
    Thread.Yield(); //tells the kernel to give other threads some time 
} 

if (timeOut) 
{ 
    Console.WriteLine("Connection Timeout"); 
    // TODO: Handle your time out here. 
} 
1

takip eder ve Bir zaman aşımı süresini aşarsa kaçış. Açıkçası, bir istisna atmak veya bu noktada durumu ele almak.

var startTime = DateTime.Now; 
var endTime = DateTime.Now.AddSeconds(5); 
var timeOut = false; 

while (_dbConnection.State == ConnectionState.Connecting) 
{ 
    if (DateTime.Now.Compare(endTime) >= 0 
    { 
     timeOut = true; 
     break; 
    } 
} 

if (timeOut) 
{ 
    // TODO: Handle your time out here. 
} 
+0

Bu senaryoda, while döngüsü hala çalışıyor ve büyük bir işlemci süresine sahip oluyor. – Omar

2

DÜZENLEME: Bu DbConnection için çalıştığını unutmayın ve IDbConnection

Hep DbConnection sınıfının yerine while döngüsünün StateChange olayını kullanabilirsiniz edin. döngü çalışır ve bazı arka plan çalışması bekleyen için geçerli bir strateji olmasına rağmen

Kontrol this

+0

Sadece merak ediyorum. Ya bağlantı hiç gelmezse? Etkinlik hiç ateş etmeyecek mi? – Omar

+0

@tou: Bu, ayrı ayrı ele alınarak Bağlantı Zaman Aşımı istisnasıyla ele alınmalıdır ... – Chandu

+0

Bu tam olarak çalışır mı? Ya aynı bağlantı geri döndüyse? İşleyicileri biriktirirsin. – Kit

0

Kanca StateChange olayı bir işleyici: Burada revize Justin'in cevabı. Durum Açık olduğunda, gerekenleri yapın.

  m_SqlConnection = new SqlConnection(ConnectionStringBuilder.ConnectionString); 
      m_SqlConnection.StateChange += new System.Data.StateChangeEventHandler(m_SqlConnection_StateChange); 
      m_SqlConnection.Open(); 



    void m_SqlConnection_StateChange(object sender, System.Data.StateChangeEventArgs e) 
    { 
     try 
     { 
      if (m_SqlConnection.State == ConnectionState.Open) 
      { 
       //do stuff 
      } 
      if (m_SqlConnection.State == ConnectionState.Broken) 
      { 
       Close(); 
      } 
      if (m_SqlConnection.State == ConnectionState.Closed) 
      { 
       Open(); 
      } 
     } 
     catch 
     { 

     } 
    } 
+0

Her durum değişikliği farklı iş parçacığı üzerinde çalıştığından bunu yapmamanızı öneririz ve bağlantı farklı bir iş parçacığı kullanıldığında tutarsızlığa neden olabilir. – Idan