我想知道从onchange事件再次注册SQL Dependency是正确的方法吗?
一个人审核我的代码并告诉我registering everything again and again after each notification. As I can recall this will create a queue each time
所以我在onchange事件中评论此代码
void OnDataChange(object sender, SqlNotificationEventArgs e)
{
BBALogger.Write("PartIndexer Service OnDataChange called start", BBALogger.MsgType.Info);
if (e.Source == SqlNotificationSource.Timeout)
{
BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Source != SqlNotificationSource.Data)
{
BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Type == SqlNotificationType.Change)
{
BBALogger.Write("PartIndexer Service Data changed detected", BBALogger.MsgType.Info);
}
else
{
BBALogger.Write(string.Format("Ignored change notification {0}/{1} ({2})", e.Type, e.Info, e.Source), BBALogger.MsgType.Warnings);
}
CallWebService();
//((SqlDependency)sender).OnChange -= OnDataChange;
//RegisterNotification();
}
看到我评论这一行
//((SqlDependency)sender).OnChange -= OnDataChange;
//RegisterNotification();
但是在评论之后我发现onchange事件是第一次触发而且它没有从第二次触发。
用正确的方法指导我。这是我的部分代码
void OnDataChange(object sender, SqlNotificationEventArgs e)
{
BBALogger.Write("PartIndexer Service OnDataChange called start", BBALogger.MsgType.Info);
if (e.Source == SqlNotificationSource.Timeout)
{
BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Source != SqlNotificationSource.Data)
{
BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Type == SqlNotificationType.Change)
{
BBALogger.Write("PartIndexer Service Data changed detected", BBALogger.MsgType.Info);
}
else
{
BBALogger.Write(string.Format("Ignored change notification {0}/{1} ({2})", e.Type, e.Info, e.Source), BBALogger.MsgType.Warnings);
}
CallWebService();
//((SqlDependency)sender).OnChange -= OnDataChange;
//RegisterNotification();
}
private void RegisterNotification()
{
string tmpdata = "";
BBALogger.Write("PartIndexer Service RegisterNotification called start", BBALogger.MsgType.Info);
System.Data.SqlClient.SqlDependency.Stop(connectionString);
System.Data.SqlClient.SqlDependency.Start(connectionString);
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT ActivityDate FROM [dbo].tablename";
dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(OnDataChange);
SqlDataReader dr = cmd.ExecuteReader();
{
if (dr.HasRows)
{
dr.Read();
tmpdata = dr[0].ToString();
}
}
dr.Dispose();
cmd.Dispose();
}
}
catch (Exception ex)
{
BBALogger.Write("PartIndexer Service RegisterNotification Error "+ex.Message.ToString(), BBALogger.MsgType.Error);
}
finally
{
BBALogger.Write("PartIndexer Service RegisterNotification called end", BBALogger.MsgType.Info);
}
}
我使用Environment.Exit(1);要关闭win服务,它应该自动重启。谢谢 感谢
答案 0 :(得分:0)
根据this article重新订阅是SQL服务器表中更改监控的正确方法:
请注意,与SqlNotification使用情况类似,如果客户端需要进一步通知,则该客户端应再次订阅。
来自CodePoject.com的偶然this令人困惑的示例重新订阅(隐藏在MessageModel.cs中):
void notifier_NewMessage(object sender, SqlNotificationEventArgs e)
{
// Indeed, the RegisterDependency call in the event hanler!
this.LoadMessage(this.Notifier.RegisterDependency());
}
看看发明者saying关于它的内容。
在我told之前,SqlDependency之前您遇到behavior,usage和memory leaks的问题。尝试使用像SqlDependencyEx这样的开源类。我用它解决了很多问题。
使用SqlDependecyEx
,您可以分别监控INSERT
,DELETE
,UPDATE
,并接收实际更改的数据(xml
)事件args对象。希望这有帮助。