程序中使用SqlDependency做了一个提醒的功能,之后发现数据库日志文件增长飞快,几天就达到了20G,大部分都是记录了这两个错误
The query notification dialog on conversation handle '{92BB494B-330B-E411-8E48-D850E6C394A8}.' closed due to the following error: '<?xml version="1.0"?><Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-8490</Code><Description>Cannot find the remote service &apos;SqlQueryNotificationService-e32e79ee-aada-435c-a8e9-1b1ad37c6a3e&apos; because it does not exist.</Description></Error>'.The query notification dialog on conversation handle '{88FCFA7E-300B-E411-8E48-D850E6C394A8}.' closed due to the following error: '<?xml version="1.0"?><Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-8470</Code><Description>Remote service has been dropped.</Description></Error>'.查了一下,有说是sql server本身的bug,http://support.microsoft.com/kb/958006/en-us但是,我用的是SQL Server  2008 r2,而且也都更新过了,其他的一些方案也都试过了,无果!
有没有哪位高人知道的?
http://rusanu.com/2007/11/10/when-it-rains-it-pours/还有一点儿,这篇文章没怎么看懂,他说的手动释放队列是什么意思,这个还没试过!

解决方案 »

  1.   

    之前查来查去都说和SqlDependency有关
      

  2.   

    The first solution to this problem is that the SqlDependency.Stop method is called too often in the application code. The general recommendation here is to call SqlDependency.Start when the application starts up and SqlDependency.Stop when the application shuts down.
      

  3.   

    please be careful when you debug an application that uses the SqlDependency class.
      

  4.   


    这个我也看到了,我实在窗体的Load事件中Start,最后在窗体的Closed事件中Stop的,应该不是这个问题
      

  5.   

       
         private void DMain_Load(object sender, EventArgs e)
            {
                    SqlDependency.Start(Base.Common.PubConstant.ConnectionString);//传入连接字符串,启动基于数据库的监听  
                    ShowMsg();
                }
            }        private bool ShowMsg()
            {
                //用DOutPlan.WorkflowID标记是否已经提醒过,-1=未提醒;1=已提醒
                StringBuilder strSql0 = new StringBuilder();
                strSql0.Append("select ID ");
                strSql0.Append(" FROM [dbo].[DOutPlan] ");
                strSql0.Append(" where IsDel=0 and DOutID<0 and WorkflowID<0  ");
                using (SqlConnection connection = new SqlConnection(Base.Common.PubConstant.ConnectionString))
                {
                    //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]  
                    using (SqlCommand command = new SqlCommand(strSql0.ToString(), connection))
                    {
                        command.CommandType = CommandType.Text;
                        connection.Open();                    SqlDependency dependency = new SqlDependency(command);
                        dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
                        SqlDataReader sdr = command.ExecuteReader();                    if (sdr.Read())
                        {
                            if (frmtime.Visible == false && form.Visible == false)
                            {
                                int x = Screen.PrimaryScreen.WorkingArea.Right - frmtime.Width;
                                int y = Screen.PrimaryScreen.WorkingArea.Bottom - frmtime.Height;
                                frmtime.Location = new Point(x, y);//设置窗体在屏幕右下角显示 
                                frmtime.Show();
                                Base.Common.DataHelper.UpdateField("DOutPlan", "WorkflowID=1", "IsDel=0 and WorkflowID<0");//标记为已提醒
                            } 
                        }
                        else
                        {
                            return false;
                        }                }
                }
                return true;
            }        private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {
                //因为是子线程,需要用invoke方法更新ui
                if (this.InvokeRequired)
                {
                    this.Invoke(new OnChangeEventHandler(dependency_OnChange), new object[] { sender, e });
                }
                Control.CheckForIllegalCrossThreadCalls = false;
                SqlDependency dependency = (SqlDependency)sender;
                //  dependency.OnChange -= dependency_OnChange;
                ShowMsg();
                
            }
            private void DMain_FormClosed(object sender, FormClosedEventArgs e)
            {
                SqlDependency.Stop(Base.Common.PubConstant.ConnectionString);//传入连接字符串,启动基于数据库的监听  
                Application.Exit();   子页面没关闭直接关闭主窗口出异常(子页面关闭函数调用了dispose方法)
            }
      

  6.   

    你自己研究一下这段东西,我不是很懂:
    A common problem with query notifications is in combination with the provided callback
    (the OnChange event handler inside the SqlDependency class) handler in your application. 
    One of the most common error messages that can occur here is the following one inside the
    event log:
    The query notification dialog on conversation handle 
    '{5925E62A-A3BA-DC11-9E8E-000C293EC5A4}.'closed due to the following error: 
    '<?xml version="1.0"?>
    <Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error">
    <Code>-8470</Code>
    <Description>Remote service has been dropped.</Description>
    </Error>'
    As you can see from the error description, the remote service has been dropped. But what
    happened here? The immediate cause of the error message is clear, because the target service
    of the query notification was dropped. But the real question is why this happens. Is it a pro-
    gramming error or a configuration error? As you’ll see in a moment, it’s neither of these errors.
    The first solution to this problem is that the SqlDependency.Stop method is called too
    often in the application code. The general recommendation here is to call SqlDependency.
    Start when the application starts up and SqlDependency.Stop when the application shuts down.
    However, sometimes it turns out that this approach doesn’t solve the problem itself. Let’s
    look how SqlDependency waits for notification messages. When you look at SQL Profiler when
    you call SqlDependency.Start, you’ll see the T-SQL query submitted by the SqlDependency
    background thread that waits for incoming notifications. See Listing 9-29.
    exec sp_executesql
    N'BEGIN CONVERSATION TIMER (''9c0b82d5-a3ba-dc11-9e8e-000c293ec5a4'')
    TIMEOUT = 120; WAITFOR(RECEIVE TOP (1) message_type_name, conversation_handle, 
    cast(message_body AS XML) as message_body from
    [SqlQueryNotificationService-6f91483f-089c-425e-afa6-0c1553ad1b52]), 
    TIMEOUT @p2;',N'@p2 int',@p2=60000
    This query will start a new conversation timer with a time-out of two minutes (120 
    seconds) and then posts a WAITFOR T-SQL statement with a time-out of one minute (60,000
    milliseconds). The idea here is that if the application exits abruptly the conversation timer will
    fire and this will cause the activated procedure attached to the queue to run; this in turn will
    clean up the SqlDependency infrastructure (the activated procedure itself, the Service 
    Broker service, and the queue). Normally the application will not disconnect abruptly, so the
    WAITFOR T-SQL statement will time out after one minute, causing the SqlDependency to post
    back the same query, which will reset the conversation timer again to two minutes. This
    means the timer is actually never firing because it is continuously moved back two minutes.
    If a notification is received, then the WAITFOR T-SQL statement will dequeue the notification
    before the one-minute time-out occurs, and after the application callback is notified, the
    SqlDependendy will again post the same query, resetting the timer again.
    The problem here is that the same query is only posted again after the application callback
    is notified. This means when the callback function is lasting longer than two minutes (or more
    precisely, the time left from the original two minutes when the query was first launched), then
    the conversation will fire and the SqlDependency infrastructure will be removed!
    The application callback (the SqlDependency.OnChange event handler) is called synchro-
    nously in the context of processing the WAITFOR T-SQL statement query result. If this callback
    exceeds what’s left from the original timer of two minutes, then the conversation timer will 
    fire and the SqlDependency infrastructure will be removed. You can easily verify this behavior
    by simply waiting in the debugger on a breakpoint set inside this callback. Shortly the SQL
    Profiler will show that the activated stored procedure was launched and the procedure itself,
    the Service Broker service, and the queue were dropped. Interestingly enough, after the appli-
    cation is resumed, the SqlDependency class creates a new infrastructure by deploying a new
    stored procedure, a new Service Broker service, and a new queue.
    Of course, a two-minute time frame to process a callback seems long enough. But there is
    one very common scenario that results in much more time: debugging. When you develop
    applications, you often spend several minutes inside the debugger before you move on. So
    please be careful when you debug an application that uses the SqlDependency class.
      

  7.   

    来自于《Pro SQL Server 2008 Service Broker》P374,这里没有定义为BUG
      

  8.   

    上面提示很明顯:Service Broker  沒有啟動,
    當你使用SqlCacheDependency,需要先啟動Service Broker服務。
      

  9.   

    上面提示很明顯:Service Broker  沒有啟動,
    當你使用SqlDependency,需要先啟動Service Broker服務。
      

  10.   

    SQL SERVER2005 打补丁后,日志文件不增长了,但数据文件仍在增长,表数据没有增加的情况下