这是我第一次需要使用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,显示"Message Received“
INSERT INTO [DEP].[dbo].[Trigger] Values(0,3)有没有人能给我一个提示,告诉我应该检查/更改什么?
我知道在依赖中只能使用Sql特性的一个子集,但我不认为我在这里做任何花哨的事情。
发布于 2013-03-22 18:03:55
,我希望这是我犯的一个愚蠢的错误。
不幸的(或幸运的?)你犯了几个错误。
首先,您需要了解查询通知将使one query失效。因此,您最多只会收到一次通知,并且您必须再次订阅(重新提交查询)如果您想收到更多notifications.
SqlNotificationEventArgs传入的。
On_SqlBitChanged就可以触发。这应该发生在SqlWatcher.SqlWatcher构造函数中,但是您需要在构造函数运行之后订阅sqlWatcher.NewMessage。在连接NewMessage事件回调之前,可以在构造函数完成之间调用On_SqlBitChanged,在这种情况下,通知将被静默忽略。
SqlWatcher.SqlWatcher中使用SqlDependency,但在此之后调用SqlWatcher.Start()时会启动它。
SqlCommand对象,设置通知,然后...丢弃该对象。除非您实际提交了查询,否则您尚未订阅任何内容。修复建议:
Start和Stop统计,在应用程序启动时调用Start。
NewMessage之前订阅了Info提交查询(call SqlComamnd.ExecuteQuery())
Stop Info,Type和Source在On_SqlBitChanged回调中,如果您的提交包含错误,这是学习的唯一途径( SqlComamnd.ExecuteQuery()将成功,即使通知请求无效)
还有一件事:不要在后台回调中调用UI代码。不能从回调调用MessageBox.Show("Message Received");,必须通过Form.Invoke通过窗体主线程进行路由。是的,我知道严格地说,MessageBox.Show确实在非UI线程上工作,但你很快就会从警告框转移到实际的交互中,然后事情就会崩溃。
https://stackoverflow.com/questions/15566966
复制相似问题