SQLDependency_OnChange-Event срабатывает только один раз.
Я работаю с SQLDependency, чтобы уведомить меня, если есть изменения в базе данных.
После запуска программы он работает отлично. Когда я делаю первое изменение, событие срабатывает. Wohoo... это здорово.
Но если я сделал второе изменение, событие не срабатывает снова. Я искал всю сеть, я думаю, но ничего не нашел об этой проблеме. Только обнаруженные проблемы, когда событие OnChange запускается в цикле.
Кто-нибудь может мне помочь?
Здесь немного фрагмента кода:
private void GetStates()
{
if (!DoesUserHavePermission())
return;
SqlDependency.Stop(con);
SqlDependency.Start(con);
using (SqlConnection cn = new SqlConnection(con))
{
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]"
cmd.Notification = null;
cmd.Dispose();
SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
cn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
state.Clear(); //In this Case "state" is a List<string>
while (dr.Read())
{
state.Add(dr.GetString(0) + "|" + dr.GetInt32(3));
}
dr.Dispose();
dr.Close();
}
}
}
}
мое событие OnChange выглядит следующим образом:
private void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dep = sender as SqlDependency;
dep.OnChange -= this.dep_OnChange;
using (SqlConnection cn = new SqlConnection(con))
{
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT Bla, Bla2, ..FROM dbo.[BLA3]";
cmd.Notification = null;
if (e.Type == SqlNotificationType.Change)
{
if (cn.State != ConnectionState.Open)
{
cn.Open();
}
using (SqlDataReader dr = cmd.ExecuteReader())
{
state.Clear(); // Clear and Refill the stringlist "state"
while (dr.Read())
{
state.Add(dr.GetString(0) + "|" + dr.GetInt32(3));
}
}
}
cn.Close();
}
}
this.GetStates(); //to go ahead and wait for a new change
}
Где проблема?
Ответы
Ответ 1
Я тоже сталкивался с этой проблемой. Вам нужно создать новый объект SqlDependency (после отмены подписки на существующий из события OnChange), а затем запустить новую команду ExecuteReader. Я получил эту идею из этого сообщения:
http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events
Это обычно имеет смысл, так как как только вы получили уведомление об изменении, вы обычно захотите повторно запросить данные.
Ответ 2
В вашем методе private void dep_OnChange(object sender, SqlNotificationEventArgs e)
после того, как вы отмените подписку на событие dep_OnChange
, вы должны снова вызвать private void GetStates()
, чтобы снова инициализировать событие dep.OnChange
.
Ответ 3
Не уверен, что это ваша проблема, но вы распоряжаетесь командой сразу после ее создания:
using (SqlCommand cmd = cn.CreateCommand())
{
...
cmd.Dispose();
Он выглядит как ошибка.
Ответ 4
Посмотри, мой друг:
dep.OnChange -= this.dep_OnChange;
вы не уволили свое событие; что неверно;
просто удалите эту строку;
Ответ 5
В GetStates():
SqlDependency.Stop(con);
SqlDependency.Start(con);
эти строки должны выполняться только при регистрации зависимостей sql в первый раз.
Ограничьте их, когда вы вызываете метод из события OnChange.