SqlDependency正确启动,但也在启动时启动

时间:2014-12-24 10:23:06

标签: c# sql-server sql-server-2008 notifications sqldependency

我在最后几天遇到了使用SQL依赖关系的麻烦。

this link中的示例中,我几乎达到了目标。 "几乎"因为事件被正确触发,而且在启动时,我调用了MyService类的Start方法。这里有我的代码,但你可以看到它的链接是相同的(或差不多的)。

我想我可以简单地插入bool值,只是为了避免初始化事件,但我认为另一种解决方案会更好。

SQLWatcher:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public enum SqlWatcherNotificationType
{
    Blocking,
    Threaded // Launch in another thread so SqlWatcher can immediately start monitoring again.
}

public class SqlWatcher : IDisposable
{
    private string ConnectionString;
    private SqlConnection Connection;
    private SqlCommand Command;
    private SqlDataAdapter Adapter;
    private DataSet Result;
    private SqlWatcherNotificationType NotificationType;

    public SqlWatcher(string ConnectionString, SqlCommand Command, SqlWatcherNotificationType NotificationType)
    {
        this.NotificationType = NotificationType;
        this.ConnectionString = ConnectionString;
        SqlDependency.Start(this.ConnectionString);
        this.Connection = new SqlConnection(this.ConnectionString);
        this.Connection.Open();
        this.Command = Command;
        this.Command.Connection = this.Connection;
        Adapter = new SqlDataAdapter(this.Command);
    }

    public void Start()
    {
        RegisterForChanges();
    }

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

    public delegate void SqlWatcherEventHandler(DataSet Result);

    public event SqlWatcherEventHandler OnChange;

    public DataSet DataSet
    {
        get { return Result; }
    }

    private void RegisterForChanges()
    {
        //Remove old dependency object
        this.Command.Notification = null;
        //Create new dependency object
        SqlDependency dep = new SqlDependency(this.Command);
        dep.OnChange += new OnChangeEventHandler(Handle_OnChange);
        //Save data
        Result = new DataSet();
        Adapter.Fill(Result);
        //Notify client of change to DataSet
        switch (NotificationType)
        {
            case SqlWatcherNotificationType.Blocking:
                OnChange(Result);
                break;
            case SqlWatcherNotificationType.Threaded:
                ThreadPool.QueueUserWorkItem(ChangeEventWrapper, Result);
                break;
        }
    }

    public void ChangeEventWrapper(object state)
    {
        DataSet Result = (DataSet)state;
        OnChange(Result);
    }

    private void Handle_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type != SqlNotificationType.Change)
            throw new ApplicationException("Failed to create queue notification subscription!");

        //Clean up the old notification
        SqlDependency dep = (SqlDependency)sender;
        dep.OnChange -= Handle_OnChange;

        //Register for the new notification
        RegisterForChanges();
    }

    public void Dispose()
    {
        Stop();
    }
}

这是MyService类:

public class MyService
{
    private static SqlWatcher SqlQueueWatcher;

    public static void Start()
    {
        string connS = MainWindow.dbContext.Database.Connection.ConnectionString + "Password=111;";
        //Build the command object we want to monitor (don't include a SqlConnection)
        SqlCommand cmd = new SqlCommand();
        cmd = new SqlCommand("SELECT CODVEI FROM dbo.ArchivioErogazioni");
        cmd.CommandType = CommandType.Text;

        //Setup the SQLWatcher
        SqlQueueWatcher = new SqlWatcher(connS, cmd, SqlWatcherNotificationType.Blocking);
        SqlQueueWatcher.OnChange += new SqlWatcher.SqlWatcherEventHandler(QueueSQLWatcher_OnChange);
        SqlQueueWatcher.Start();
    }

    private static void QueueSQLWatcher_OnChange(DataSet Result)
    {
        //Do something with the updated DataSet object
        Debug.WriteLine("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");  ---> ENTERS HERE IN THE INIT PHASE
    }

    public static void Stop()
    {
        SqlQueueWatcher.Dispose();
    }
}

这就是我简单地称之为:

MyService.Start();

布尔旗是个坏主意吗?为什么它在启动时进入QueueSQLWatcher_OnChange?

1 个答案:

答案 0 :(得分:0)

要解决此问题,您只需将SqlCommand的通知设置为空。

 cmd.Notification = null;

试试这个,我认为你的问题将得到解决。在使用SqlWatcher

启动依赖项之前输入此行