Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не прослеживается логика в работе SqlDependency... 
:(
    Опции темы
CyraxZ
Дата 10.9.2007, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Вот фрагмент из книги про SQL Server 2005:

Код

Листинг 8-2. Код уведомлений о запросах для связанного элемента управления DataGridView.

private delegate void RefreshData();

private void btnNotification_Click(object Sender, EventArgs e)
{
    LoadData();
}

private void LoadData()
{
    SqlConnection cn = new SqlConnection(ConnString);
    SqlCommand cm = new SqlCommand("Select LastName, EmailAddress from Person.Contact", cn);
    SqlDataAdapter da = new SqlDataAdapter();
    DataTable dt = new DataTable();

    SqlDependency sd = new SqlDependency(cm);
    sd.OnChange += new OnChangeEventHandler(ContactInfoChanged);
    SqlDependency.Start(ConnString);

    da.Fill(dt);

    dgvContacts.DataSource = dt;
}

private void ContactInfoChanged(object caller, SqlNotificationEventArgs e)
{
    Invoke(new RefreshData(LoadData));
}

private void frmBindingTest_FormClosing(object sender, FormClosingEventArgs e)
{
    SqlDependency.Stop(ConnString);
}

Обратите внимание, что в самом начале определения класса объявлен делегат с именем
RefreshData. Функция LoadData, возвращающая void, играет роль универсального загрузчика
данных и вызывается из обработчика события Click элемента управления btnNotifications. В теле
функции LoadData объект cm передаётся конструктору объекта SqlDependency, а функция
обратного вызоваContactInfoChanged регистрируется в качестве обработчика для события
OnChange этого объекта. Также вызывается статический метод SqlDependency.Start, которому в
качестве параметра передаётся строка подключения, используемая для выполнения запроса. Весь
код, относящийся к объекту SqlDependency размещён перед вызовом метода Fill объекта
DataAdapter. Функция обратного вызова вызывается при любом поступлении уведомления о запросе,
и в свою очередь, при помощи объявленного нами делегата вновь вызывает функцию LoadData,
чтобы обновить отображаемые данные. Наконец, чтобы корректно завершить работу, в
обработчике события закрытия формы FormClosing вызывается статический метод
SqlDependency.Stop.


Предварительно запрос ALTER DATABASE Person SET ENABLE_BROKER для своей БД выполнил. Выполнил успешно.

Абсолютно не понятна логика работы SqlDependency:
1. Почему при генерации события sd.OnChange в обработчике ContactInfoChanged вызывать
всю процедуру LoadData (в которой заново создаются объекты SqlDataAdapter и SqlDependency,
заново добавляем в событие sd.OnChange свой обработчик, заново вызываем метод
SqlDependency.Start). Ведь в обработчике всего лишь должно обрабатываеться изменение данных. В
приведённом примере достаточно было вызвать метод da.Fill(dt) и всё.
Не деструктурируется же сам по себеобъект SqlDependency после первой генерации события
OnChange...

2. Почему-то событие OnChange вызывается только при добавлении обработчика
sd.OnChange += new OnChangeEventHandler(ContactInfoChanged);
Если в обработчике ContactInfoChanged вызвыть все операторы метода Load, кроме "sd.OnChange
+= new OnChangeEventHandler(ContactInfoChanged);", то событие будет сгенерировано только один
раз - когда мы нажимаем кнопку btnNotification.
Собственно, проверил это на следующем коде:

Код

public bool StartMonitoring()
{
connectionString = "server=Cyrax\\SQLEXPRESS;database=Br;Integrated Security=True";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("Select ChannelID, Value From Br.dbo.ASData", connection);
dataAdapter = new SqlDataAdapter(command);

dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(ChangeSignal);
            
ASDataTable = new DataTable();

SqlDependency.Start(connectionString);
dataAdapter.Fill(ASDataTable);
}

public void ChangeSignal(object Sender, SqlNotificationEventArgs e)
{
dataAdapter.Fill(ASDataTable);  // здесь ставлю точку останова
}


В приведённом коде метод ChangeSignal вызывается только один раз не зависимо от внешнего изменения данных в БД Br.
Если в обработчик ChangeSignal добавить фрагмент
Код

dataAdapter = new SqlDataAdapter(command);
dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(ChangeSignal);
SqlDependency.Start(connectionString);

то он (обработчик ChangeSignal) начнёт вызываться без конца без изменения данных в БД. Да это и
логично: мы в обработчике ChangeSignal каждый раз создаём и запускаем новый SqlDependency,
который один раз сразу же генерирует событие OnChange после вызова SqlDependency.Start.

3. Что в выражении "Функция обратного вызова вызывается при любом поступлении
уведомления о запросе" означает "поступлении уведомления о запросе" ?
Что значит "уведомление о запросе" ?  Кто это уведомление отправляет и кому, и в каком виде ?
И уведомление о каком запросе ?  О запросе на что ?

В общем, ничего не понятно в работе этого SqlDependency...
Я представляю работу подобного механизма так:  один раз в коде создаём SqlDependency,
настраиваем, все дела, запускаем и всё. При любом изменении данных (соответственно SqlCommand)
вызывается указанный обработчик, в котором мы делаем что угодно. Он (обработчик) может быть
пустым - и это никак не должно повлиять на работу этого механизма. Т.е. в обработчике мы ничего
не должны делать по обслуживанию SqlDependency...

Это сообщение отредактировал(а) CyraxZ - 10.9.2007, 22:45
PM MAIL   Вверх
CyraxZ
Дата 11.9.2007, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Неужели никто не работал с SQL Server'ом ?
mr.DUDA и zaver наверняка в курсе сабжа...
PM MAIL   Вверх
mr.DUDA
Дата 12.9.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



С этой чудной SqlDependency - увы - не пришлось работать. А сейчас и Sql Server-а нет в наличии чтобы потестить, т.к. давно от bizdev'а отошёл  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
compaq
Дата 7.11.2009, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 20.11.2006

Репутация: нет
Всего: нет



CyraxZ
Ну как разобрался как работает SqlDependency. А то я тоже разбираюсь и для меня не совсем понятен механизм его работы?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.0753 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.