从onchange事件再次注册SQL依赖项

时间:2015-04-24 14:46:48

标签: c# sqldependency

我想知道从onchange事件再次注册SQL Dependency是正确的方法吗?

一个人审核我的代码并告诉我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);

        }

}

我使用Environment.Exit(1);要关闭win服务,它应该自动重启。谢谢 感谢

1 个答案:

答案 0 :(得分:0)

根据this article重新订阅是SQL服务器表中更改监控的正确方法:

  

请注意,与SqlNotification使用情况类似,如果客户端需要进一步通知,则该客户端应再次订阅

来自CodePoject.com的偶然this令人困惑的示例重新订阅(隐藏在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之前您遇到behaviorusagememory leaks的问题。尝试使用像SqlDependencyEx这样的开源类。我用它解决了很多问题。 使用SqlDependecyEx,您可以分别监控INSERTDELETEUPDATE,并接收实际更改的数据(xml)事件args对象。希望这有帮助。