Каков предпочтительный способ сообщения кода сервера нескольким клиентам об изменениях данных в одном приложении Delphi?

У меня есть большое приложение Delphi, в котором есть основной «серверный» код, содержащий мои данные. В рамках одного и того же приложения, «клиента», пользователь может открывать и закрывать несколько немодальных «клиентских» форм для проверки этих данных. Изменения данных делятся на два типа: основные (например, структурные изменения, такие как добавление или удаление данных) и второстепенные, такие как изменение значения данных. Существующие открытые клиентские формы должны обновляться, чтобы отображать измененные данные в кратчайшие сроки. Это не база данных, это мой «сервер», использующий мои собственные структуры данных, поэтому в моих решениях, возможно, пропущены стандартные методы, доступные в формальной структуре базы данных. Тем не менее, я повторял свои решения так много раз, что подумал, что могу спросить, есть ли формальные методы и, возможно, компоненты Delphi, которые улучшили бы или упростили мой код. Я собираюсь перейти к многопоточному коду, что делает этот вопрос еще более актуальным для меня.

Я использую два метода:

  1. Отметка времени. «Серверный» код поддерживает значение Int64, взятое из QueryPerformanceCounter. Клиентские формы проверяют это значение на тикающем таймере 300 мс и обновляют себя, если их копия временной метки отличается от серверной. Думаю, это мое решение "тянуть".

  2. Уведомление интерфейса.«Серверный» код поддерживает класс, производный от TInterfaceList, с методами AddClient и RemoveClient, которые регистрируют простой общий интерфейс уведомления клиента. Каждый из клиентов регистрируется в этом списке при создании и отменяет регистрацию при уничтожении. Изменения данных на сервере запускают итерацию по этому списку, вызывая каждого клиента, чтобы сообщить ему об изменении. Я предполагаю, что это мое «толкающее» решение.

Мне нравятся интерфейсы, и решение 2 кажется приятным, поскольку оно позволяет избежать тикающих таймеров и легко отлаживается (хотя вызовы отмены регистрации могут вызывать проблемы с порядком уничтожения). Это также может сказаться на производительности, потому что вполне вероятно, что могут происходить тысячи изменений данных в секунду, и мне нужно быть осторожным, чтобы использовать механизм BeginUpdate / EndUpdate для преобразования множества изменений данных сервера в один фактический вызов уведомления. В конечном итоге мне нужен какой-то таймер, чтобы объединить вызовы в одно плавное обновление отображаемой формы.

Оба решения работают хорошо, и я разрываюсь между ними. Я уверен, что для многопоточного решения есть и другие подводные камни, о которых я ничего не знаю. Любые замечания будут оценены. Использую XE2.

21
задан Brian Frost 27 February 2012 в 09:30
поделиться