Nic*_*ams 5 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=******";
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;
Run Code Online (Sandbox Code Playgroud)
在我的主窗口中,我有这个
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");
}
}
Run Code Online (Sandbox Code Playgroud)
所以预期的行为是,如果我运行以下sqlQuery,将显示一个消息框,说"收到消息"
INSERT INTO [DEP].[dbo].[Trigger] Values(0,3)
Run Code Online (Sandbox Code Playgroud)
谁能给我一个关于检查/更改内容的提示?
我知道只有一部分Sql功能可用于依赖项,但我不认为我在这里想做任何事情.
Rem*_*anu 22
我希望这是我犯过的一个愚蠢的错误.
不幸的是(或者幸运的是?)你犯了几个错误.
首先,您需要了解查询通知将使一个查询无效.因此,您最多只会收到一次通知,如果您想再收到通知,则必须重新订阅(重新提交查询).
接下来,您需要了解您将收到任何原因的通知,而不仅仅是更改.在你的回调中,你必须检查你被通知的原因,这些原因是通过SqlNotificationEventArgs.
接下来,您需要了解异步编程的基本原则:如果您订阅了一个事件,请确保在事件第一次发生之前订阅.例证:提交查询后,On_SqlBitChanged可以立即触发.这应该在构造函数中发生,但是您在构造函数运行之后订阅.可以在挂钩事件回调之前在构造函数完成之间调用,在这种情况下,将自动忽略通知.SqlWatcher.SqlWatchersqlWatcher.NewMessage On_SqlBitChangedNewMessage
如果要使用服务,请确保在使用之前启动它.您正在使用SqlDependency SqlWatcher.SqlWatcher但是在您调用之后启动它SqlWatcher.Start().
最后,如果您希望收到有关查询更改的通知,则必须提交查询.您正在构建SqlCommand对象,设置通知然后...丢弃对象.除非您实际提交查询,否则您尚未订阅任何内容.
修复建议:
Start和Stop静态,Start在应用程序启动时调用.NewMessage 在提交查询之前订阅SqlComamnd.ExecuteQuery())Info,Type并Source在On_SqlBitChanged回调中,如果您的提交包含错误,这是唯一的学习方法(即使通知请求无效,SqlComamnd.ExecuteQuery()也会成功)还有一件事:不要在后台回调中调用UI代码.你不能MessageBox.Show("Message Received");从回调中调用,你必须通过表单主线程路由Form.Invoke.是的,我知道严格来说MessageBox.Show 确实可以在非UI线程上运行,但是你很快就会从警告框中移开来实际形成交互,然后事情就会破裂.
| 归档时间: |
|
| 查看次数: |
15195 次 |
| 最近记录: |