用sqlDependency来监控数据库是否有更新,数据库是本机的,也没有用任何程序进行更改,
测试代码也是在网上找的公用代码,但是sqlDependency的onChange事件总是一直不停的触发,就大神帮忙解决一下。
代码如下:
class Program
    {
        private static string _connStr= "data source=.;initial catalog=isa;uid=sa;pwd=zxcvbnm;";        static void Main(string[] args)
        {
            SqlDependency.Start(_connStr);//传入连接字符串,启动基于数据库的监听
            UpdateGrid();            Console.Read();        }        private static void UpdateGrid()
        {
            using (SqlConnection connection = new SqlConnection(_connStr))
            {
                //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]
                using (SqlCommand command = new SqlCommand("select FLTID,LEGNO,DEPSTN,ARRSTN,[STATUS] From [dbo].[FLIGHTS] where fltid<10", connection))
                {
                    command.CommandType = CommandType.Text;
                    connection.Open();
                    SqlDependency dependency = new SqlDependency(command);
                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);                    SqlDataReader sdr = command.ExecuteReader();
                    Console.WriteLine();
                    while (sdr.Read())
                    {
                        Console.WriteLine("FLTID:{0}\t LEGNO:{1}\t DEPSTN:{2}\t ARRSTN:{3}\t STATUS:{4}", sdr["FLTID"].ToString(), sdr["LEGNO"].ToString(), sdr["DEPSTN"].ToString(), sdr["ARRSTN"].ToString(), sdr["STATUS"].ToString());
                    }
                    sdr.Close();
                }
            }
        }        private static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            //SqlDependency dependency = sender as SqlDependency;
            //dependency.OnChange -= dependency_OnChange;  
            UpdateGrid();
        }    }

解决方案 »

  1.   

    你设计的这个流程有些“奇怪”。你在 UpdateGrid 里边执行 dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);然后在 dependency_OnChange 里边由执行 UpdateGrid()。这样不“疯”才怪呢。自己设计流程吧。
      

  2.   

    一般来说,从最“被动”的角度来修改,可以写成dependency.OnChange -= new OnChangeEventHandler(dependency_OnChange);
    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);但是更好的办法是搞明白实际应该暴露的方法是什么(不应该暴露的方法应该声明为private等等),正确设计流程。
      

  3.   

    你把自己的程序流程找一张纸画出来(画出来才容易记忆,代码并不容易记忆),也可以帮助你今后设计正确的流程。按照你的程序流程,第二次数据表改变时UpdateGrid 会被执行2次,第三次数据表改变时UpdateGrid 会被执行4次,第四次数据表改变时UpdateGrid 会被执行8次,.........第11次改变数据表时UpdateGrid 会被执行上千次。
      

  4.   


    我是要一直监听数据库库的表变化啊
    关键是现在数据库里面的数据没变化,就不应该会到dependency_OnChange方法里面,这个问题出在哪儿??
      

  5.   

    dependency_OnChange里面你屏蔽那两段代码干啥?private  void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        SqlDependency dependency = (SqlDependency)sender;
        dependency.OnChange -= dependency_OnChange;
        RegisterOnChangeEvent(); 
    }只“+”不“-”?
    另外
    using (SqlCommand command = new SqlCommand("select FLTID,LEGNO,DEPSTN,ARRSTN,STATUS From dbo.FLIGHTS where fltid<10", connection))
      

  6.   

    还有 sqlDependency 我以前用的时候 发现网上说存在内存泄漏的问题没有很好的解决, 不过我到没遇到过  不知道是不是真有问题(可能是因为量小还是什么原因的)。 看你是才接触sqlDependency ,大项目你还是慎用较好
      

  7.   

     我也碰到了,发送我把数据库名称[dataName].[dbo].[tableName]也带上了,后面去掉就好了,只留下[dbo].[tableName] ,不过楼主的不是这样的问题,希望对后面的朋友有帮助
      

  8.   

    我也遇到这个问题,查了两天资料,按楼上的方法去掉[dataName]就正常了,虽然楼主已经发贴有一年了,但为给以后网友多一个参考的方案,我附上我的代码:
    public partial class Form1 : Form
        {
            private string conStr = "Data Source=.;Database=AdventureWorks;Uid=sa;Pwd=wxh;Pooling=true;Connect Timeout=60;";
            private string cmdStr = "SELECT ProductID, [Name], ProductNumber, Color, SafetyStockLevel, ListPrice FROM Production.Product";
            public Form1()
            {
                InitializeComponent();
            }
            private void Form1_Load(object sender, EventArgs e)
            {
                SqlDependency.Start(conStr);
                UpdateData();
            }
            private void UpdateData()
            {
                SqlDataAdapter da = new SqlDataAdapter(cmdStr, conStr);
                SqlDependency dependency = new SqlDependency(da.SelectCommand);
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
                DataTable dt = new DataTable();
                da.Fill(dt);
               this.dataGridView1.Invoke((MethodInvoker)delegate
                    {
                        this.dataGridView1.DataSource = dt;
                    });
            }
            private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {
                if (e.Info == SqlNotificationInfo.Insert ||
                  e.Info == SqlNotificationInfo.Update ||
                  e.Info == SqlNotificationInfo.Delete)
                {
                    UpdateData();
                }
            }
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                SqlDependency.Stop(conStr);
            }
        }没更改之前的cmdStr是:
            private string cmdStr = "SELECT ProductID, [Name], ProductNumber, Color, SafetyStockLevel, ListPrice FROM AdventureWorks.Production.Product";
          dataGridView1就一直在闪。
      

  9.   

                //if (e.Info == SqlNotificationInfo.Insert || e.Info == SqlNotificationInfo.Update || e.Info == SqlNotificationInfo.Delete)
                //{
                //    UpdateGrid();
                //}你这样 能触发? 我测试不可能的,人家本来就要不断的查询