-->

电平变化的SqlDependency没有发射(SqlDependency OnChange Not

2019-07-22 14:08发布

这是我所需要使用的SqlDependency所以我希望它是一个愚蠢的错误,我做的第一次。

我遇到的问题是,给onChanged事件不火的SQL表发生变化时。 没有错误或任何东西只是它不火。

下面是代码

public class SqlWatcher
{
    private const string SqlConnectionString = "Data Source = CN-PC08\\DEV; Initial Catalog=DEP; User = sa; Password=******";

    public SqlWatcher()
    {
        SqlClientPermission perm = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
        perm.Demand();

        SqlCommand cmd = new SqlCommand("SELECT [DataAvaliable], [RowNumber] FROM [dbo].[Trigger]", new SqlConnection(SqlConnectionString));
        SqlDependency sqlDependency = new SqlDependency(cmd);
        sqlDependency.OnChange += On_SqlBitChanged;
    }

    private void On_SqlBitChanged(object sender, SqlNotificationEventArgs sqlNotificationEventArgs)
    {
        SqlDependency dependency = (SqlDependency)sender;
        dependency.OnChange -= On_SqlBitChanged;

        // Fire the event
        if (NewMessage != null)
        {
            NewMessage(this, new EventArgs());
        }
    }

    public void Start()
    {
        SqlDependency.Start(SqlConnectionString);
    }

    public void Stop()
    {
        SqlDependency.Stop(SqlConnectionString);
    }

    public event EventHandler NewMessage;

而在我的主窗口,我有这个

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        try
        {
            SqlWatcher sqlWatcher = new SqlWatcher();
            sqlWatcher.Start();
            sqlWatcher.NewMessage += On_NewMessage;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

    private void On_NewMessage(object sender, EventArgs eventArgs)
    {
        MessageBox.Show("Message Received");
    }
}

因此,预期的行为是,如果我运行下面的SQLQuery一个消息框将显示说:“收到消息”

INSERT INTO [DEP].[dbo].[Trigger] Values(0,3)

任何人都可以给我什么检查/变化的暗示?

我知道,只有SQL功能的子集可以依赖中使用,但我不认为我试图做任何事情看中这里。

Answer 1:

我希望它是一个愚蠢的错误,我做。

不幸的是(或幸运?)你正在几次失误。

  1. 首先是你要明白,查询通知将失效一个查询 。 如果你希望再收到通知,所以你只会在最一旦接到通知,你必须再重新订阅(重新提交查询)。

  2. 接下来,你需要明白,你会以任何理由通知,不仅更改。 在你的回调,你必须检查它通过传递在你通知的原因, SqlNotificationEventArgs

  3. 接下来,你需要了解异步编程的基本原则:如果您订购的事件一定要订阅事件之前可能发生第一次。 案例分析:在On_SqlBitChanged可以,只要你提交查询开火。 这应该在发生SqlWatcher.SqlWatcher构造,但你订阅sqlWatcher.NewMessage构造函数运行之后On_SqlBitChanged可以与你挂钩的前构造完成调用NewMessage事件回调在这种情况下,通知被忽略。

  4. 如果你想使用的服务,确保您使用它之前,你开始吧。 您正在使用的SqlDependency在SqlWatcher.SqlWatcher ,但之后你启动它,当你调用SqlWatcher.Start()

  5. 最后,如果你希望收到的查询的变化,你必须提交查询 。 您正在构建SqlCommand对象,设置通知,然后...丢弃的对象。 除非你确实提交查询,你还不订阅任何东西

为修复建议:

  • StartStop静,调用Start应用程序启动。
  • 请确保您订阅NewMessage您提交的查询之前
  • 事实上提交查询(调用SqlComamnd.ExecuteQuery()
  • 检查InfoTypeSourceOn_SqlBitChanged回调,如果您提交包含一个错误,这是学习(在SqlComamnd.ExecuteQuery()会成功,即使通知请求是无效的)的唯一途径
  • 您必须重新订阅一旦你收到通知的改变,再次执行查询。

还有一两件事:不要在后台调用回调UI代码。 你不能调用MessageBox.Show("Message Received"); 从回调,则必须经由形式主线路线Form.Invoke 。 是的,我知道,严格说来MessageBox.Show 在非UI线程工作,但你很快就会从警告框,以实际上形成互动搬开,然后事情会打破。



文章来源: SqlDependency OnChange Not Firing