C# 对命名队列使用SqlDependency

C# 对命名队列使用SqlDependency,c#,sql-server,sql-server-2008,sqldependency,C#,Sql Server,Sql Server 2008,Sqldependency,我有以下代码,它使用SqlDependency来监视我的一个数据库中的更改它工作得很好,除了每次运行它都会使用数据库中的guid生成自己的队列/服务/路由之外: 类别: class SqlWatcher { private string connectionString; private string sqlQueue; private string listenerQuery; private SqlDependency dependency; pub

我有以下代码,它使用SqlDependency来监视我的一个数据库中的更改它工作得很好,除了每次运行它都会使用数据库中的guid生成自己的队列/服务/路由之外:

类别:

class SqlWatcher
{
    private string connectionString;
    private string sqlQueue;
    private string listenerQuery;
    private SqlDependency dependency;

    public SqlWatcher(string connectionString, string sqlQueue, string listenerQuery)
    {
        this.connectionString = connectionString;
        this.sqlQueue = sqlQueue;
        this.listenerQuery = listenerQuery;
        this.dependency = null;
    }

    public void Start()
    {
        SqlDependency.Start(connectionString);
        ListenForChanges();
    }

    public void Stop()
    {
        SqlDependency.Stop(this.connectionString);
    }

    private void ListenForChanges()
    {
        //Remove existing dependency, if necessary
        if (dependency != null)
        {
            dependency.OnChange -= onDependencyChange;
            dependency = null;
        }

        SqlConnection connection = new SqlConnection(connectionString);
        connection.Open();

        SqlCommand command = new SqlCommand(listenerQuery, connection);

        dependency = new SqlDependency(command);

        // Subscribe to the SqlDependency event.
        dependency.OnChange += new OnChangeEventHandler(onDependencyChange);

        SqlDependency.Start(connectionString);

        command.ExecuteReader();

        //Perform this action when SQL notifies of a change
        performAction();

        connection.Close();
    }

    private void onDependencyChange(Object o, SqlNotificationEventArgs args)
    {
        if ((args.Source.ToString() == "Data") || (args.Source.ToString() == "Timeout"))
        {
            Console.WriteLine(System.Environment.NewLine + "Refreshing data due to {0}", args.Source);
            ListenForChanges();
        }
        else
        {
            Console.WriteLine(System.Environment.NewLine + "Data not refreshed due to unexpected SqlNotificationEventArgs: Source={0}, Info={1}, Type={2}", args.Source, args.Info, args.Type.ToString());
        }
    }

    private void performAction()
    {
        Console.WriteLine("Performing action");
    }
}
执行:

static void Main(string[] args)
{
   string connectionString = @"<MY CONNECTION STRING>"; 
   string sqlQueue = @"NamesQueue";

   //Listener query restrictions: http://msdn.microsoft.com/en-us/library/aewzkxxh.aspx
   string listenerQuery = "SELECT Value FROM dbo.Table WHERE Name = 'Test'";

   SqlWatcher w = new SqlWatcher(connectionString, sqlQueue, listenerQuery);
   w.Start();
   Thread.Sleep(10000);
   w.Stop();
}
并修改了我的C#代码以使用此队列和服务:

...
SqlDependency.Start(connectionString, sqlQueue);
...
SqlDependency.Stop(this.connectionString, sqlQueue);
...
dependency = new SqlDependency(command, "service=NamesService;local database=<MY DB>", 0);
...
SqlDependency.Start(connectionString,sqlQueue);
...
。。。
Start(connectionString,sqlQueue);
...
SqlDependency.Stop(this.connectionString,sqlQueue);
...
dependency=newsqldependency(命令,“service=NamesService;localdatabase=”,0);
...
Start(connectionString,sqlQueue);
...
当我运行代码时,进行这些代码更改不会导致动态创建队列,但是我的代码不再工作,我的应用程序也无法识别对我的表/查询所做的更改


我花了好几天的时间试图解决这个问题,但都没有成功,有人能提供一些建议吗?谢谢。

找到了答案-错误在我的SQL CREATE语句中。我使用的是:

CREATE SERVICE NamesService ON QUEUE NamesQueue;
但是根据,CREATE SERVICE命令需要使用contract_name参数,以便允许其他对话框以正在创建的服务为目标

因此,使用下面的CREATE语句修复了我的问题:

CREATE SERVICE NamesService
ON QUEUE NamesQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]) ;
使用类时要小心,因为它有内存泄漏。您可以使用SqlDependency类的开源实现-。它使用数据库触发器和本机ServiceBroker通知来接收有关表更改的事件。这是一个使用示例:

int changesReceived=0;
使用(SqlDependencyEx SqlDependencyEx=new SqlDependencyEx(
测试\连接\字符串、测试\数据库\名称、测试\表\名称)
{
sqlDependency.TableChanged+=(o,e)=>changesReceived++;
sqlDependency.Start();
//更改表格。
MakeTableInsertDeleteChanges(changesCount);
//请稍等,以接收所有更改。
睡眠(1000);
}
断言.AreEqual(changesCount,changesReceived);

希望这能有所帮助。

多亏了您问题中的代码,我终于能够成功地设置SqlDependency。。。到目前为止,我一直在犯一些非常隐晦的错误(或者根本没有错误,只是整个事情都不起作用)。我想知道为什么很难找到关于这个的好例子。。。无论如何,谢谢!
CREATE SERVICE NamesService
ON QUEUE NamesQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]) ;