2015-04-24 4 views
1

Я реализовал sql-зависимость в службе Windows. когда данные будут изменены в таблице, тогда произойдет событие onchange, и оттуда я вызываю веб-службу.Sql Dependency onchange событие не срабатывает каждый раз C#

Я поделюсь своим полным кодом. Я тестировал много раз на своем ПК, прежде чем устанавливать службу Windows на ПК производства. Предположим, что если я устанавливаю на ПК производства сегодня, то он работает на сегодняшний день, но когда я тестирую на следующий день, его событие onchange не срабатывало.

поэтому я нашел onchange событие стрельбы только в первый день и со следующего дня onchange event не стрелял. Возможно, я ошибся в коде. так что это моя просьба, пожалуйста, кто-нибудь посмотрит мой код в деталях и поможет мне, где я допустил ошибку, для которой она не работает должным образом.

public partial class PartIndexer : ServiceBase 
{ 
    static string connectionString = "server=xxx;uid=xxx;password=xxx;database=xxx;Pooling=true;Connect Timeout=20;"; 
    SqlDependency dep; 

    public PartIndexer() 
    { 
     InitializeComponent(); 
    } 

    private string GetLoggedInUser() 
    { 
     string userName = ""; 
     if (System.Security.Principal.WindowsIdentity.GetCurrent() != null) 
     { 
      userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name; 
     } 
     return userName; 
    } 

    #region OnStart 
    protected override void OnStart(string[] args) 
    { 
     BBALogger.Write("PartIndexer Service OnStart called start", BBALogger.MsgType.Info); 
     RegisterNotification(); 
     MailSend(); // notification mail send 
     BBALogger.Write("PartIndexer Service OnStart called end, logged in user " + GetLoggedInUser(), BBALogger.MsgType.Info); 
    } 
    #endregion 

    #region RegisterNotification 
    /// <summary> 
    /// RegisterNotification 
    /// this is main routine which will monitor data change in ContentChangeLog table 
    /// </summary> 
    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 TestTable FROM [dbo].ContentChangeLog"; 
       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); 

     } 

    } 
    #endregion 

    #region OnDataChange 
    /// <summary> 
    /// OnDataChange 
    /// OnDataChange will fire when after data change found in ContentChangeLog table 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void OnDataChange(object sender, SqlNotificationEventArgs e) 
    { 
     ((SqlDependency)sender).OnChange -= OnDataChange; 

     BBALogger.Write("PartIndexer Service RegisterNotification called end", BBALogger.MsgType.Info); 

     if (e.Source == SqlNotificationSource.Timeout) 
     { 
    MailSend(); // notification mail send 
    BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error); 

      Environment.Exit(1); 
     } 
     else if (e.Source != SqlNotificationSource.Data) 
     { 
     MailSend(); // notification mail send 
      BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error); 

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

     RegisterNotification(); 
    } 
    #endregion 

    #region StartIndex 
    /// <summary> 
    /// StartIndex 
    /// this routine will call web service in bba reman website which will invoke routine to re-index data 
    /// </summary> 
    void StartIndex() 
    { 
     // calling web service if change is notified 

    } 
    #endregion 

    #region MailSend 
    /// <summary> 
    /// MailNotify 
    /// fire mail when apps start & exit 
    /// </summary> 
    /// <param name="strStatus"></param> 
    void MailSend() 
    { 
    // mail send code 
    } 
    #endregion 

    #region OnStop 
    protected override void OnStop() 
    { 
     BBALogger.Write("PartIndexer Service StartIndex called end, logged in user " + GetLoggedInUser(), BBALogger.MsgType.Info); 
     System.Data.SqlClient.SqlDependency.Stop(connectionString); 
     MailNotify("STOPPED"); 
    } 
    #endregion 
} 

Другой вопрос, который я заметил, что когда я начинаю обслуживание окон и оставить его работать на один день, тогда, когда я пытаюсь остановить или перезапустить службу окон, то я окна служба не может быть остановлена. Это означает, что в моем коде есть некоторые недостатки, которые я не могу указать. поэтому, пожалуйста, помогите мне. благодаря

+0

Неверная общая логика. Например, вы регистрируете все снова и снова после каждого уведомления. Как я помню, это создаст очередь каждый раз. Посмотрите на эту ссылку и внесите необходимые изменения кода: http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach –

+0

Я не говорю, что мой код не работает. Я нашел некоторое время, когда событие OnDataChange не срабатывает. Я сказал, что моя логика неверна. Могу ли вы, пожалуйста, подчеркнуть ту линию, которую вы думаете не правильно. – Mou

+0

Создание очереди каждый раз вызывает проблему? – Mou

ответ

1

я только что заметил, что вы использовали

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

старт SQL зависимость и остановить внутри RegisterNotification() функции, но не правильный путь, и это может вызвать проблемы вызвать событие в следующий раз. он может работать один раз правильно.

вы просто пытаетесь использовать в окнах начинает функцию

#region OnStart 
    protected override void OnStart(string[] args) 
    { 

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

     BBALogger.Write("PartIndexer Service OnStart called start", BBALogger.MsgType.Info); 
     RegisterNotification(); 
     MailSend(); // notification mail send 
     BBALogger.Write("PartIndexer Service OnStart called end, logged in user " + GetLoggedInUser(), BBALogger.MsgType.Info); 
    } 
    #endregion 

я надеюсь, что это позволит решить проблему, спасибо.

+0

он разрешил мою проблему, вы спасли мой день – usman

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