Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SqlDependency OnChange未触发_C#_Sql_Sql Server_Sqldependency - Fatal编程技术网

C# SqlDependency OnChange未触发

C# SqlDependency OnChange未触发,c#,sql,sql-server,sqldependency,C#,Sql,Sql Server,Sqldependency,这是我第一次需要使用SqlDependency,所以我希望这是我犯的一个愚蠢的错误 我遇到的问题是,当sql表更改时,OnChanged事件不会触发。没有错误或任何事情,只是它不会开火 这是密码 public class SqlWatcher { private const string SqlConnectionString = "Data Source = CN-PC08\\DEV; Initial Catalog=DEP; User = sa; Password=******";

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

我遇到的问题是,当sql表更改时,OnChanged事件不会触发。没有错误或任何事情,只是它不会开火

这是密码

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,将显示一个messageBox,显示“MessageReceived”

谁能给我一个提示,告诉我该检查/更改什么

我知道依赖项中只能使用Sql特性的一个子集,但我不认为我想做什么来满足这里的需求

我希望这是我犯的愚蠢的错误

不幸的是(或幸运的是?)你犯了几个错误

  • 首先,您需要了解查询通知将使一个查询失效。因此,您最多只会收到一次通知,如果您希望收到更多通知,则必须再次重新订阅(重新提交查询)

  • 接下来,您需要了解,您将收到任何原因的通知,而不仅仅是更改。在回调中,您必须检查收到通知的原因,这些原因通过
    SqlNotificationEventArgs
    传入

  • 接下来,您需要了解异步编程的基本原则:如果您订阅了一个事件,请确保在事件第一次发生之前订阅。举个例子:只要您提交查询,上的
    就可以启动。这应该发生在
    SqlWatcher.SqlWatcher
    构造函数中,但在构造函数运行后,您可以订阅
    SqlWatcher.NewMessage
    <在挂接
    NewMessage
    事件回调之前,可以在构造函数完成之间调用\u SqlBitChanged
    ,在这种情况下,会自动忽略通知

  • 如果要使用某项服务,请确保在使用前启动该服务。您正在
    SqlWatcher.SqlWatcher
    中使用SqlDependency,但是在调用
    SqlWatcher.start()
    之后,您会启动它

  • 最后,如果您希望收到查询更改的通知,则必须提交查询。您正在构造
    SqlCommand
    对象,设置通知,然后。。。丢弃该对象。除非您确实提交了查询,否则您尚未订阅任何内容

  • 修复建议:

    • 进行
      Start
      Stop
      静态,在应用程序启动中调用
      Start
    • 提交查询之前,请确保订阅了
      NewMessage
    • 实际提交查询(调用
      SqlComamnd.ExecuteQuery()
    • 检查
      On_SqlBitChanged
      回调中的
      信息
      类型
      ,如果您的提交包含错误,这是唯一的了解方法(即使通知请求无效,sqlcoamnd.ExecuteQuery()也会成功)
    • 您必须在收到更改通知后重新订阅,然后再次执行查询

    还有一件事:不要在后台回调中调用UI代码。您不能调用
    MessageBox.Show(“消息已接收”)从回调,必须通过表单主线程路由。是的,我知道严格地说,
    MessageBox.Show
    在非UI线程上可以工作,但您很快就会离开警报框,真正形成交互,然后事情就会破裂。

    认为任何试图寻找sqldependencyEx解决方案的人都应该使用sqldependencyEx。这里可以找到简单的连接步骤。
    INSERT INTO [DEP].[dbo].[Trigger] Values(0,3)