I am using the SqlDependency to notify me of data changes in a table. However, as soon as I start it, the OnChange event fires over and over even though no data has changed.
Essentially All I want to do is be notified when records are inserted into a table. I am able to get another example to work using a Service Broker Queue and a sql query of WAITFOR ( RECEIVE CONVERT(int, message_body) AS msg FROM QueueMailReceiveQueue ) However I would prefer not to use a queue for once my messages have been read they are taken off the queue and I would rather control that manually.
Any help with getting SqlDependency to notify my app when records are added and not over and over when the data has changed would be great.
Here is my code:
public
partialclassForm1 : Form {
publicstaticeventOnChangeEventHandler OnChange;
string _strConnString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=email_queue;Pooling=False;";
string _strSql = "SELECT email_id from email where isprocessed = 0";
privateDataSet dataToWatch = null;
privateSqlConnection connection = null;
privateSqlCommand command = null;
SqlDependency dependency = null;
SqlDataReader sdr = null;
public Form1() {
InitializeComponent();
}
privatevoid button1_Click(object sender, EventArgs e) {
SqlDependency.Stop(_strConnString);
SqlDependency.Start(_strConnString);
if (connection == null) {
connection = newSqlConnection(_strConnString);
connection.Open();
}
if (command == null) {
command = newSqlCommand(_strSql, connection);
}
if (dataToWatch == null) {
dataToWatch = newDataSet();
}
GetData();
}
privatevoid GetData() {
dataToWatch.Clear();
command.Notification = null;
dependency = newSqlDependency(command);
dependency.OnChange += newOnChangeEventHandler(dependency_OnChange);
command.CommandTimeout = 400;
using (SqlDataAdapter adapter = newSqlDataAdapter(command)) {
adapter.Fill(dataToWatch, "email");
}
}
privatevoid dependency_OnChange(object sender, SqlNotificationEventArgs e) {
ISynchronizeInvoke i = (ISynchronizeInvoke)this;
if (i.InvokeRequired) {
OnChangeEventHandler tempDelegate = newOnChangeEventHandler(dependency_OnChange);
object[] args = { sender, e };
i.BeginInvoke(tempDelegate, args);
return;
}
dependency = (SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
this.Text = DateTime.Now.ToString();
GetData();
}
privatevoid Form1_FormClosed(object sender, FormClosedEventArgs e) {
SqlDependency.Stop(_strConnString);
if (connection != null) {
connection.Close();
}
}
}