2012-02-24 20 views
15

Estoy trabajando con SQLDependency para notificarme si hay un cambio en la base de datos. Después de la puesta en marcha del programa, funciona bien. Cuando hago un primer cambio, el evento se dispara. Wohoo ... eso es genial. Pero si hice un segundo cambio, el evento no se dispara nuevamente. He buscado en toda la web, creo, pero no he encontrado nada sobre ESTE problema. Solo se encontraron problemas en los que OnChange-Event se activa en un bucle. ¿Alguien puede ayudarme?SQLDependency_OnChange-Event activa solo una vez Tiempo

Aquí una pequeña pieza de código:

private void GetStates() 
    { 
     if (!DoesUserHavePermission()) 
      return; 

     SqlDependency.Stop(con); 
     SqlDependency.Start(con); 

     using (SqlConnection cn = new SqlConnection(con)) 
     { 
      using (SqlCommand cmd = cn.CreateCommand()) 
      { 
       cmd.CommandType = CommandType.Text; 
       cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]" 

       cmd.Notification = null; 
       cmd.Dispose(); 

       SqlDependency dep = new SqlDependency(cmd); 
       dep.OnChange += new OnChangeEventHandler(dep_OnChange); 

       cn.Open(); 

       using (SqlDataReader dr = cmd.ExecuteReader()) 
       { 
        state.Clear(); //In this Case "state" is a List<string> 
        while (dr.Read()) 
        { 
         state.Add(dr.GetString(0) + "|" + dr.GetInt32(3)); 
        } 
        dr.Dispose(); 
        dr.Close(); 
       }      
      } 
     } 
    } 

mi AlCambiar-Evento se ve así:

private void dep_OnChange(object sender, SqlNotificationEventArgs e) 
    { 
     SqlDependency dep = sender as SqlDependency; 
     dep.OnChange -= this.dep_OnChange; 

     using (SqlConnection cn = new SqlConnection(con)) 
     { 
      using (SqlCommand cmd = cn.CreateCommand()) 
      { 
       cmd.CommandType = CommandType.Text; 
       cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]"; 

       cmd.Notification = null; 

       if (e.Type == SqlNotificationType.Change) 
       { 
        if (cn.State != ConnectionState.Open) 
        { 
         cn.Open(); 
        } 

        using (SqlDataReader dr = cmd.ExecuteReader()) 
        { 
         state.Clear(); // Clear and Refill the stringlist "state" 
         while (dr.Read()) 
         { 
          state.Add(dr.GetString(0) + "|" + dr.GetInt32(3)); 
         } 
        } 
       } 
       cn.Close(); 
      } 
     } 
     this.GetStates(); //to go ahead and wait for a new change 
    } 

¿Dónde está el problema?

+0

tiene que iniciar SqlDependency nuevamente después de la llamada al evento por primera vez. por lo que no se romperá para el segundo evento y así sucesivamente. funcionará perfectamente – adnan

Respuesta

2

No estoy seguro si ese es su problema, pero se deshaga el comando justo después de que lo haya creado:

using (SqlCommand cmd = cn.CreateCommand()) 
{ 
    ... 
    cmd.Dispose(); 

Se ve como un insecto.

+0

Ese código de ejemplo de Microsoft hace lo mismo. Lo intenté en ambos sentidos, y el evento todavía parece disparar solo una vez. – BlueMonkMN

8

Me encontré con este problema también. Debe crear una nueva entidad SqlDependency (después de anular la suscripción del existente del evento OnChange) y luego ejecutar un nuevo comando ExecuteReader. Tengo la idea de este post:

http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events

Esto por lo general tiene sentido, ya que una vez se le ha notificado de un cambio que normalmente se desee volver a consultar los datos.

1

Mira mi amigo:

dep.OnChange -= this.dep_OnChange; 

que un-despedido de su evento; que no es verdad; simplemente borre esta línea;

+2

Tiene que hacer eso, porque una nueva dependencia se creará siempre. Este es un evento de cambio único. – Marshal

0

En getStates():

SqlDependency.Stop(con); SqlDependency.Start(con);

estas líneas deben ser ejecutados sólo cuando el registro de la dependencia de sql por primera vez.

Restringirlos cuando llame al método desde el evento OnChange.

3

En el método de private void dep_OnChange(object sender, SqlNotificationEventArgs e) después de darse de baja del evento dep_OnChange debe llamar a la private void GetStates() de nuevo, para inicializar el evento dep.OnChange nuevo.

Cuestiones relacionadas