每次c#都没有触发Sql依赖onchange事件

时间:2015-04-24 09:27:48

标签: c# windows-services sqldependency

我在windows服务中实现了sql依赖。当数据将在表中更改时,onchange事件将触发,并从那里调用Web服务。

我将分享我的完整代码。我在PC上测试了很多次,然后在生产PC上安装Windows服务。假设我今天在生产PC上安装,那么今天它可以工作,但是当我第二天测试时,它的onchange事件没有解雇。

所以我发现onchange事件仅在第一天和第二天的onchange事件中被解雇。可能是我在代码中犯了一些错误。所以这是我的要求,请有人看到我的代码详细信息,并帮助我在哪里犯了错误,因为它无法正常工作。

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
}

另一个问题我注意到,当我启动Windows服务并让它运行一天然后当我尝试停止或重新启动Windows服务时,我的Windows服务无法停止。这意味着我的代码肯定存在一些缺陷,我无法指出。所以请帮帮我。感谢

1 个答案:

答案 0 :(得分:1)

我刚注意到你使用了

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

sql依赖项在RegisterNotification()函数内启动和停止,但其方法不正确,可能导致问题下次调用事件。它可能正常工作一次。

你只是尝试在windows启动功能中使用

    #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

我希望它能解决你的问题,谢谢。