Я реализовал sql-зависимость в службе Windows. когда данные будут изменены в таблице, тогда произойдет событие onchange, и оттуда я вызываю веб-службу.Sql Dependency onchange событие не срабатывает каждый раз C#
Я поделюсь своим полным кодом. Я тестировал много раз на своем ПК, прежде чем устанавливать службу Windows на ПК производства. Предположим, что если я устанавливаю на ПК производства сегодня, то он работает на сегодняшний день, но когда я тестирую на следующий день, его событие onchange не срабатывало.
поэтому я нашел onchange событие стрельбы только в первый день и со следующего дня onchange event не стрелял. Возможно, я ошибся в коде. так что это моя просьба, пожалуйста, кто-нибудь посмотрит мой код в деталях и поможет мне, где я допустил ошибку, для которой она не работает должным образом.
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
}
Другой вопрос, который я заметил, что когда я начинаю обслуживание окон и оставить его работать на один день, тогда, когда я пытаюсь остановить или перезапустить службу окон, то я окна служба не может быть остановлена. Это означает, что в моем коде есть некоторые недостатки, которые я не могу указать. поэтому, пожалуйста, помогите мне. благодаря
Неверная общая логика. Например, вы регистрируете все снова и снова после каждого уведомления. Как я помню, это создаст очередь каждый раз. Посмотрите на эту ссылку и внесите необходимые изменения кода: http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach –
Я не говорю, что мой код не работает. Я нашел некоторое время, когда событие OnDataChange не срабатывает. Я сказал, что моя логика неверна. Могу ли вы, пожалуйста, подчеркнуть ту линию, которую вы думаете не правильно. – Mou
Создание очереди каждый раз вызывает проблему? – Mou