i have implemented sql dependency in windows service. when data will be changed in table then onchange event will fire and from there i am invoking a web service.
i will share my full code. i tested many time in my pc before installing the window service production pc. i works. suppose if i install in production pc today then it works for today but when i test next day then i was onchange event not firing.
so i found onchange event firing only first day and from the next day onchange event not firing. may be i made some mistake in code. so it is my request please some one see my code in details and help me where i made the mistake for which it is not working properly.
public partial class PartIndexer : ServiceBase
{
static string connectionString = "server=xxx;uid=xxx;password=xxx;database=xxx;Pooling=true;Connect Timeout=20;";
SqlDependency dep;
public PartIndexer()
{
InitializeComponent();
}
private string GetLoggedInUser()
{
string userName = "";
if (System.Security.Principal.WindowsIdentity.GetCurrent() != null)
{
userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
return userName;
}
#region OnStart
protected override void OnStart(string[] args)
{
BBALogger.Write("PartIndexer Service OnStart called start", BBALogger.MsgType.Info);
RegisterNotification();
MailSend(); // notification mail send
BBALogger.Write("PartIndexer Service OnStart called end, logged in user " + GetLoggedInUser(), BBALogger.MsgType.Info);
}
#endregion
#region RegisterNotification
/// <summary>
/// RegisterNotification
/// this is main routine which will monitor data change in ContentChangeLog table
/// </summary>
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 TestTable FROM [dbo].ContentChangeLog";
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);
}
}
#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)sender).OnChange -= OnDataChange;
BBALogger.Write("PartIndexer Service RegisterNotification called end", BBALogger.MsgType.Info);
if (e.Source == SqlNotificationSource.Timeout)
{
MailSend(); // notification mail send
BBALogger.Write("PartIndexer Service SqlNotificationSource.Timeout error", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Source != SqlNotificationSource.Data)
{
MailSend(); // notification mail send
BBALogger.Write("PartIndexer Service SqlNotificationSource.Data", BBALogger.MsgType.Error);
Environment.Exit(1);
}
else if (e.Type == SqlNotificationType.Change)
{
StartIndex();
BBALogger.Write("PartIndexer Service Data changed", BBALogger.MsgType.Info);
}
else
{
BBALogger.Write(string.Format("Ignored change notification {0}/{1} ({2})", e.Type, e.Info, e.Source), BBALogger.MsgType.Warnings);
}
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 StartIndex()
{
// calling web service if change is notified
}
#endregion
#region MailSend
/// <summary>
/// MailNotify
/// fire mail when apps start & exit
/// </summary>
/// <param name="strStatus"></param>
void MailSend()
{
// mail send code
}
#endregion
#region OnStop
protected override void OnStop()
{
BBALogger.Write("PartIndexer Service StartIndex called end, logged in user " + GetLoggedInUser(), BBALogger.MsgType.Info);
System.Data.SqlClient.SqlDependency.Stop(connectionString);
MailNotify("STOPPED");
}
#endregion
}
another issue i noticed that when i start my windows service and leave it run in one day when i try to stop or restart the the windows service then i saw windows can not stop the service. it means definitely there is some flaw in my code which i am not being
able to point out. so please help me.
one guy review my code and said i am creating queue each time that causes problem ?
is it true that my code will create a queue each time. if yes then creating queue each time causes what kind of problem ? need details. thanks