none
SqlDependency 发生客户端通知 RRS feed

  • 问题

  • 创建SqlDependency,并注册OnChange事件之后,等待数据库通知。长时间之后(大约20个小时)会获得一个来自客户端的通知,此时OnChange事件参数SqlNotificationEventArgs中的Type = Changed; Info = Error; Source = Client。我会在每次OnChange事件时重新注册一个新的SqlDependency监听数据,但是发生客户端通知之后就失效了,请问如何解决?

            private void Dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {
                SqlDependency dependency = sender as SqlDependency;
                dependency.OnChange -= Dependency_OnChange;

                //执行数据操作

                DependencyChanged.SqlDependencyOnChange(sender, e);

                //重新注册SqlDependency

                DependencyStart();
            }

    2010年6月2日 4:19

答案

  • 问题找到了,超时的原因是因为网络不稳定,网络连接中断导致数据库连接超时。希望能对其它遇到此问题的朋友有些帮助,感谢各位解答~~
    • 已标记为答案 Song0116 2010年6月3日 2:26
    2010年6月3日 2:26

全部回复

  • 你好!

        你这行代码:

    SqlDependency dependency = sender as SqlDependency;

        声明的是局部变量,当函数结束,这个变量的生命周期也就结束了!

       你把这个变量声明为成员变量试试!


    周雪峰
    2010年6月2日 4:58
    版主
  • 我曾经试过声明成成员的,但是问题依然。我想知道Source = Client到底是哪里出问题了,帮助文档解释Client(发生了客户端启动的通知(如由于发生客户端超时,或试图向已激发的依赖项添加命令)),这里客户端超时是什么东西超时了,超时的时间是否可以设置?

    2010年6月2日 5:06
  • 你好!~

    这里dependency.OnChange -= Dependency_OnChange;是要取消订阅吗?


    周雪峰
    2010年6月2日 5:48
    版主
  • 你好!~

    这里dependency.OnChange -= Dependency_OnChange;是要取消订阅吗?


    周雪峰
    是的,取消订阅。保证事件只触发一次,以免死循环。之后SqlDependency 对象就已经失效了,在我处理完数据之后我会重新再创建一个新的SqlDependency 并注册事件等待下一次数据库推送。
    2010年6月2日 5:51
  • 你好!    请问可以多提供一些代码吗?这些代码很难发现问题啊!
    周雪峰
    2010年6月2日 6:10
    版主
  • 你好!    请问可以多提供一些代码吗?这些代码很难发现问题啊!
    周雪峰


    我顺序贴代码了,调用顺序就是代码的顺序

    先是调用SqlDependency.Start()

            public bool DependencyInit()
            {
                bool result = false;
                try
                {
                    SqlDependency.Stop(ConnectionStrings.DefaultConnectionString);
                    result = SqlDependency.Start(ConnectionStrings.DefaultConnectionString);
                    return result;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            }

    然后注册一个SqlDependency

            public virtual void DependencyStart()
            {
                using (_connection = new SqlConnection(ConnectionStrings.DefaultConnectionString))
                {
                    if (_connection.State != ConnectionState.Open)
                        _connection.Open();
                    SqlCommand cmd = new SqlCommand(DependencyCommand, _connection);
                    cmd.CommandType = CommandType.Text;
                    dependency = new SqlDependency(cmd);
                    dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);
                    cmd.ExecuteNonQuery();
                    _connection.Close();
                }
            }

    最后就是调用OnChange事件了

            private void Dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {
                dependency.OnChange -= Dependency_OnChange;

                if (e.Info == SqlNotificationInfo.Error) //这里我试着在发生错误的时候重新注册但是完全无效
                {
                    Console.WriteLine("出现内部服务器错误!");
                    bool flag = DependencyInitAndStart();
                    Console.WriteLine(flag.ToString());
                    DependencyStart();
                    return;
                }
                DependencyChanged.SqlDependencyOnChange(sender, e);
            }

    下面是SqlDependencyOnChange方法,处理数据操作的

            public virtual void SqlDependencyOnChange(object sender, System.Data.SqlClient.SqlNotificationEventArgs e)
            {
                ...连接数据库
                //重新注册SqlDependency
                _dependency.DependencyStart();

                ...获取并更新需要的数据,太长了就不贴了,和SqlDependency也没什么关系,操作期间的SqlConnection等数据库操作对象全部是重新创建的

             }

    2010年6月2日 6:21
  • 对了,订阅通知的语句是 SELECT changeId FROM [dbo].[SqlCacheForChangeDependency] WHERE tableName = 'SynchronizationDataStack'
    2010年6月2日 6:23
  • 问题找到了,超时的原因是因为网络不稳定,网络连接中断导致数据库连接超时。希望能对其它遇到此问题的朋友有些帮助,感谢各位解答~~
    • 已标记为答案 Song0116 2010年6月3日 2:26
    2010年6月3日 2:26