2011-06-13 15 views
5

estaba revisando el código para conectarse a la base de datos en una de las aplicaciones que estoy trabajando y vi estaLa mejor manera de no hacer nada hasta que las cosas están conectadas en C#

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; 

El tiempo preocupaciones de bucle yo. ¿Hay una mejor manera de hacer nada hasta que las cosas estén conectadas?

EDIT:

La conexión se consigue de la siguiente manera

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

¿Qué tipo de conexión? System.Data.SqlClient.SqlConnection? –

+1

Haría un tiempo de espera y pondré en el bucle while una instrucción delay/wait para no perder el tiempo de la CPU – Earlz

+0

La clase de la conexión es System.Data.IDbConnection – Omar

Respuesta

5

Aunque el bucle funciona y es una estrategia válida para la espera de alguna operación en segundo plano, otras respuestas parecen perder un punto clave; tienes que dejar que la operación en segundo plano haga algo de trabajo. Batir a través de un bucle while no es muy productivo, pero Windows considerará el hilo principal de la aplicación, que es probablemente lo que está esperando, que es de gran importancia, y recorrerá el ciclo cientos o miles de veces antes de la operación de fondo. obtiene un solo reloj de tiempo de CPU.

Para evitar esto, utilice la instrucción Thread.Yield() para indicarle al procesador que pase por todos los otros subprocesos que esperan el tiempo de CPU y regresen cuando hayan terminado. Esto permite que la computadora realice un trabajo mientras espera el proceso en segundo plano, en lugar de monopolizar la CPU para que gire a través de un bucle básicamente vacío. Es realmente simple; aquí está la respuesta de Justin revisada:

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

considerando que es una aplicación web, lo mejor que puede hacer es calcular la duración del tiempo transcurrido desde que empezó a tratar de conectar y escapar si excede un período de tiempo de espera. Obviamente, lanza una excepción o maneja la situación en ese punto.

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

En este escenario, el bucle while aún se está ejecutando y obtiene una gran parte del tiempo del procesador. – Omar

2

EDITAR: Tenga en cuenta que esto funciona para DbConnection y no IDbConnection

Siempre se puede utilizar el evento stateChange de la clase DbConnection en lugar del bucle while.

Comprobar this

+0

Solo me pregunto. ¿Qué pasa si la conexión nunca llega? ¿El evento nunca se disparará? – Omar

+0

@tou: Esto debe abordarse mediante el tratamiento de excepciones de tiempo de espera de conexión por separado ... – Chandu

+0

¿Funcionaría completamente? ¿Qué ocurre si se devuelve la misma conexión? Acumularías controladores. – Kit

0

Enganche un controlador en el evento StateChange. Cuando el estado está abierto, haga lo que necesite.

  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

, no recomendaría hacer esto, ya que cada cambio de estado se está ejecutando en un hilo diferente, y podría causar inconsistencia al usar la conexión de un hilo diferente. – Idan

Cuestiones relacionadas