2015-04-24 2 views
1

Мне нравится знать, правильно ли это относится к регистрации SQL Dependency снова из события onchange?Регистрация SQL Dependency снова из события onchange

один парень пересмотреть свой код и сказал мне registering everything again and again after each notification. As I can recall this will create a queue each time

поэтому я комментировать этот код в OnChange событие

void OnDataChange(object sender, SqlNotificationEventArgs e) 
     { 
      BBALogger.Write("PartIndexer Service OnDataChange called start", BBALogger.MsgType.Info); 

      if (e.Source == SqlNotificationSource.Timeout) 
      { 
       BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error); 
       Environment.Exit(1); 
      } 
      else if (e.Source != SqlNotificationSource.Data) 
      { 
       BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error); 
       Environment.Exit(1); 
      } 
      else if (e.Type == SqlNotificationType.Change) 
      { 
       BBALogger.Write("PartIndexer Service Data changed detected", BBALogger.MsgType.Info); 
      } 
      else 
      { 
       BBALogger.Write(string.Format("Ignored change notification {0}/{1} ({2})", e.Type, e.Info, e.Source), BBALogger.MsgType.Warnings); 
      } 

      CallWebService(); 
      //((SqlDependency)sender).OnChange -= OnDataChange; 
      //RegisterNotification(); 
     } 

просто увидеть я закомментировать эту строку

//((SqlDependency)sender).OnChange -= OnDataChange; 
    //RegisterNotification(); 

, но после того, как комментирование я нашел onchange событие стреляет в первый раз, и он не стреляет со второго раза.

руководство меня с правильным подходом. здесь мой неполный код

void OnDataChange(object sender, SqlNotificationEventArgs e) 
{ 
    BBALogger.Write("PartIndexer Service OnDataChange called start", BBALogger.MsgType.Info); 

    if (e.Source == SqlNotificationSource.Timeout) 
    { 
    BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error); 
    Environment.Exit(1); 
    } 
    else if (e.Source != SqlNotificationSource.Data) 
    { 
    BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error); 
    Environment.Exit(1); 
    } 
    else if (e.Type == SqlNotificationType.Change) 
    { 
    BBALogger.Write("PartIndexer Service Data changed detected", BBALogger.MsgType.Info); 
    } 
    else 
    { 
    BBALogger.Write(string.Format("Ignored change notification {0}/{1} ({2})", e.Type, e.Info, e.Source), BBALogger.MsgType.Warnings); 
    } 

    CallWebService(); 
    //((SqlDependency)sender).OnChange -= OnDataChange; 
    //RegisterNotification(); 
} 


private void RegisterNotification() 
    { 
     string tmpdata = ""; 
     BBALogger.Write("PartIndexer Service RegisterNotification called start", BBALogger.MsgType.Info); 

     System.Data.SqlClient.SqlDependency.Stop(connectionString); 
     System.Data.SqlClient.SqlDependency.Start(connectionString); 

     try 
     { 
     using (SqlConnection conn = new SqlConnection(connectionString)) 
     { 
      conn.Open(); 
      SqlCommand cmd = conn.CreateCommand(); 
      cmd.CommandText = "SELECT ActivityDate FROM [dbo].tablename"; 
      dep = new SqlDependency(cmd); 
      dep.OnChange += new OnChangeEventHandler(OnDataChange); 
      SqlDataReader dr = cmd.ExecuteReader(); 
      { 
      if (dr.HasRows) 
      { 
       dr.Read(); 
       tmpdata = dr[0].ToString(); 
      } 
      } 
      dr.Dispose(); 
      cmd.Dispose(); 
     } 
     } 
     catch (Exception ex) 
     { 
     BBALogger.Write("PartIndexer Service RegisterNotification Error "+ex.Message.ToString(), BBALogger.MsgType.Error); 
     } 
     finally 
     { 
     BBALogger.Write("PartIndexer Service RegisterNotification called end", BBALogger.MsgType.Info); 

     } 

} 

i use Environment.Exit (1); к завершению работы по завершению работы, в результате он должен перезапуститься автоматически. спасибо благодаря

ответ

0

Согласно this article повторной подписки правильный подход для мониторинга изменений в таблицах сервера SQL:

Обратите внимание, как, по аналогии с использованием SqlNotification, клиент, как ожидается подписаться снова если он хочет получить дополнительную информацию.

Даже this запутанным пример из CodePoject.com делает повторную подписку (скрытый в MessageModel.cs):

void notifier_NewMessage(object sender, SqlNotificationEventArgs e) 
{ 
    // Indeed, the RegisterDependency call in the event hanler! 
    this.LoadMessage(this.Notifier.RegisterDependency()); 
} 

и посмотреть на то, что изобретатель saying об этом.

Как я told вас перед SqlDependency имеет проблемы с behavior, usage и memory leaks. Попробуйте использовать классы с открытым исходным кодом, такие как SqlDependencyEx. Я решил много проблем с этим. С SqlDependecyEx вы в состоянии контролировать INSERT, DELETE, UPDATE отдельно и получить фактические измененные данные (xml) в случае объектно арг. Надеюсь, эта помощь.

+0

Я заинтересован в использовании SqlDependecyEx, и здесь вы сказали, что мы можем отслеживать INSERT, DELETE, UPDATE отдельно и получать фактические измененные данные (xml) в объекте args события, но как ...... Мне нужен пример кода SqlDependecyEx для контролировать INSERT, DELETE, UPDATE отдельно, а также получать измененные данные в формате xml. нужен полный код. – Mou

+0

@Mou Вот полные примеры, которые вам нужны: https://github.com/dyatchenko/ServiceBrokerListener/issues/5#issuecomment-96284037 – dyatchenko

+0

Я видел, что некоторые данные не заполняются в этой системной таблице 'dm_qn_subscriptions'' select * from sys.dm_qn_subscriptions' – Mou

Смежные вопросы