I pulled an example from this MSDN page and used it quite a bit verbatim. When the code works correctly, compilation is performed correctly, but changeCount infinitely increasing whether the data has really changed. When a change has occurred, dataGridView1 correctly reflects the change. Why does my SqlDependency seem like it is shooting in a loop, although apparently there were no changes?
Here's the source:
#region Using directives using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Text; using System.Windows.Forms; #endregion namespace PreAllocation_Check { public partial class Form1 : Form { int changeCount = 0; const string tableName = "MoxyPosition"; const string statusMessage = "Last: {0} - {1} changes."; DataSet dataToWatch = null; SqlConnection MoxyConn = null; SqlCommand SQLComm = null; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { if (CanRequestNotifications()) { SqlDependency.Start(GetConnectionString()); if (MoxyConn == null) MoxyConn = new SqlConnection(GetConnectionString()); if (SQLComm == null) { SQLComm = new SqlCommand(GetSQL(), MoxyConn); SqlParameter prm = new SqlParameter("@Quantity", SqlDbType.Int); prm.Direction = ParameterDirection.Input; prm.DbType = DbType.Int32; prm.Value = 100; SQLComm.Parameters.Add(prm); } if (dataToWatch == null) dataToWatch = new DataSet(); GetData(); } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { SqlDependency.Stop(GetConnectionString()); if (MoxyConn != null) MoxyConn.Close(); } private bool CanRequestNotifications() { try { SqlClientPermission SQLPerm = new SqlClientPermission(PermissionState.Unrestricted); SQLPerm.Demand(); return true; } catch { return false; } } private string GetConnectionString() { return "server=***;database=***;user id=***;password=***"; } private void GetData() { dataToWatch.Clear(); SQLComm.Notification = null; SqlDependency SQLDep = new SqlDependency(SQLComm); SQLDep.OnChange += new OnChangeEventHandler(SQLDep_OnChange); using (SqlDataAdapter adapter = new SqlDataAdapter(SQLComm)) { adapter.Fill(dataToWatch, tableName); dataGridView1.DataSource = dataToWatch; dataGridView1.DataMember = tableName; } } private string GetSQL() { return "SELECT PortID, CONVERT(money, SUM(PreAllocPos), 1) AS PreAllocation, CONVERT(money, SUM(AllocPos), 1) AS Allocation, CONVERT(money, SUM(PreAllocPos) - SUM(AllocPos), 1) AS PreLessAlloc " + "FROM MoxyPosition " + "WHERE CONVERT(money, PreAllocPos, 1) <> CONVERT(money, AllocPos, 1) " + "GROUP BY PortID " + "ORDER BY PortID ASC;"; } void SQLDep_OnChange(object sender, SqlNotificationEventArgs e) { ISynchronizeInvoke i = (ISynchronizeInvoke)this; if (i.InvokeRequired) { OnChangeEventHandler tempDelegate = new OnChangeEventHandler(SQLDep_OnChange); object[] args = { sender, e }; i.BeginInvoke(tempDelegate, args); return; } SqlDependency SQLDep = (SqlDependency)sender; SQLDep.OnChange -= SQLDep_OnChange; changeCount++; DateTime LastRefresh = System.DateTime.Now; label1.Text = String.Format(statusMessage, LastRefresh.TimeOfDay, changeCount); GetData(); } } }
Edit: It is worth noting that the broker service is not currently enabled in the database with which I want to run this function, so to check my code, I backed up my target database and restored it with a new name, then performed ALTER DATABASE my_db_name SET ENABLE_BROKER against it. All my tests were on this alternative database, which means that I am the only user on it.
newuser
source share