【发布时间】:2014-10-06 17:37:35
【问题描述】:
我的 SqlDependency 代码正在侦听来自 Windows 服务的表中的插入/更新,当我启动该服务时,它会在接下来的 2/3 天工作,然后停止工作。
我在这里粘贴我的完整代码。
public partial class PartIndexer : ServiceBase
{
static string connectionString = "MyConnection String;Pooling=true;Connect Timeout=20;";
SqlDependency dep;
public PartIndexer()
{
InitializeComponent();
}
#region OnStart
protected override void OnStart(string[] args)
{
System.Data.SqlClient.SqlDependency.Stop(connectionString);
System.Data.SqlClient.SqlDependency.Start(connectionString);
RegisterNotification();
MailNotify("STARTED");
}
#endregion
#region RegisterNotification
/// <summary>
/// RegisterNotification
/// this is main routine which will monitor data change in ContentChangeLog table
/// </summary>
private void RegisterNotification()
{
string tmpdata = "";
//eventLog1.WriteEntry("RegisterNotification invoked");
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT ActivityDate FROM [bba-reman].ContentChangeLog";
dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(OnDataChange);
SqlDataReader dr = cmd.ExecuteReader();
{
while (dr.Read())
{
if (dr[0] != DBNull.Value)
{
tmpdata = dr[0].ToString();
}
}
}
dr.Dispose();
cmd.Dispose();
}
}
finally
{
//SqlDependency.Stop(connStr);
}
}
#endregion
#region OnDataChange
/// <summary>
/// OnDataChange
/// OnDataChange will fire when after data change found in ContentChangeLog table
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnDataChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dep = sender as SqlDependency;
dep.OnChange -= new OnChangeEventHandler(OnDataChange);
SendMailNotification();
RegisterNotification();
}
#endregion
#region StartIndex
/// <summary>
/// StartIndex
/// this routine will call web service in bba reman website which will invoke routine to re-index data
/// </summary>
void SendMailNotification()
{
// does some job
}
#endregion
#region MailNotify
/// <summary>
/// MailNotify
/// fire mail when apps start & exit
/// </summary>
/// <param name="strStatus"></param>
void MailNotify(string strStatus)
{
if (strStatus == "STARTED")
{
var template = new MailTemplate()
.WithBody("HI,<br><br>Part Indexer Started Date " + DateTime.Now.ToLongDateString())
.WithSubject("Part Indexer Started")
.WithSender("xxxxx")
.WithRecepient("xxxx")
.Send();
}
else if (strStatus == "STOPPED")
{
var template = new MailTemplate()
.WithBody("HI,<br><br>Part Indexer stopped Date " + DateTime.Now.ToLongDateString())
.WithSubject("Part Indexer Stopped")
.WithSender("xxx")
.WithRecepient("xxx")
.Send();
}
}
#endregion
#region OnStop
protected override void OnStop()
{
System.Data.SqlClient.SqlDependency.Stop(connectionString);
MailNotify("STOPPED");
}
#endregion
}
我从这个网址看到另一个人面临同样的问题SqlDependency error after a long time
他说发生超时错误。根据他的建议,我将代码更改为
void OnDataChange(object sender, SqlNotificationEventArgs e)
{
((SqlDependency)sender).OnChange -= OnDataChange;
//SqlDependency dep = sender as SqlDependency;
//dep.OnChange -= new OnChangeEventHandler(OnDataChange);
if (e.Source == SqlNotificationSource.Timeout)
{
// just restart notification
RegisterNotification();
return;
}
else if (e.Source != SqlNotificationSource.Data)
{
ReStartService();
}
SendMailNotification();
RegisterNotification();
}
只看这行代码
if (e.Source == SqlNotificationSource.Timeout)
{
// just restart notification
RegisterNotification();
return;
}
else if (e.Source != SqlNotificationSource.Data)
{
Environment.Exit(1);
}
如果发生超时,那么我将再次调用 RegisterNotification() 函数。 我在阅读该网址后写了这些行,但不确定上面的行会做什么?
所以请指导我是否走在正确的轨道上?请帮助我使我的应用程序没有错误,以便它可以长时间收听而不会出现任何问题。谢谢
【问题讨论】:
-
您在服务的恢复选项卡上设置了哪些选项?
-
@Donal : 不清楚你想问什么?
-
@Donal:我没有为我的服务设置任何恢复选项,只是有默认设置。默认设置为:First Failure -- 重新启动服务。如果我停止服务而不是重新启动,我的服务会重新启动吗?
-
恢复选项卡仅在您的服务出现故障时使用 - 如果您手动将其关闭。
-
SQLDependency 的问题是它只允许少数请求,我有一个监控应用程序的 SQLDependencies,但事实证明它容易出错,我认为微软说它只允许一次 10 个“依赖项”,然后它重置 - 我相信关闭连接的问题
标签: c# sql-server windows-services sqldependency