Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как бы управлять порядком уничтожения компонентов? [D7]


PVOzerski ©   (2005-03-16 12:20:00) 

Сейчас делаю наборчик компонентов, позволяющих работать с некой локальной БД из нескольких потоков. Сделал компонент-сервер и подключающийся к нему компонент-клиент (наследник tDataSet со свойством Server). При этом клиентов у одного сервера может быть несколько.

В нынешнем варианте компоненты кладутся на форму, таким образом она и оказывается их Owner'ом. И из-за этого возникает проблема. А именно: при уничтожении формы она уничтожает компоненты в "своем" порядке и может уничтожить серверный раньше его клиентов, которые не успеют сделать, условно говоря, "прощальные" закрытия.

Первое, что хотелось сделать, - динамически переназначать Owner'а серверу с формы на компоненты-клиенты at run-time. По рассмотрении кода components.pas, стало ясно, что штатным образом это не сделать. Какие-нибудь идеи есть?


MalkoLinge   (2005-03-16 19:36:00) [1]

ИМХО
1.Нотификация об уничтожении сервера для обнуления ссылок клиентов.
2. Побочным эффектом свойства Server для компонента  клиента  сделать безопасное отключение клиента от сервера.
И не надо никаких счетчиков ссылок и объектов без владельцев. Ибо 1. не решит это проблемы , как было замечно выше, явного прибития серверного объекта.
2. Не решит проблемы некорректного отключения клиента от сервера (нормально не решит).


Димон   (2005-03-16 18:19:00) [2]

я бы тоже пользовался notification.


Набережных С.   (2005-03-16 18:08:00) [3]

Ну то есть программист, использующий твой компонент, напишет в коде Server.Free и будет свято верить, что прихлопнул соединение(и это, имхо, логично). А на самом деле соединение будет продолжать существовать. Свежий подход:) Дело, конечно, твое, но мне вот не понятно - на кой ляд? Уже существует стандартный механизм нотификации, ничего не надо делать. Просто перекрыть у клиента метод Notification, а при назначении/обнулении его свойства Server вызывать соответственно FreeNotification/RemoveFreeNotification сервера, в случае, если клиент и сервер находятся в разных контейнерах. Все, получаем нормальное, привычное и логичное поведение без всяких дополнительных объектов и списков.


PVOzerski   (2005-03-16 16:38:00) [4]

В общем, задачу решил так. "Серверный" компонент теперь занимается серверными делами не сам, а из порождает экземпляр "настоящего серверного" класса, не имеющего Owner'a, зато имеющего счетчик подключенных клиентов. Как только счетчик обнуляется, вызывается деструктор. А чтобы он не уничтожился, если все клиенты отключились временно, одним из клиентов регистрируется сам "серверный" компонент, породивший этот экземпляр.


icWasya   (2005-03-16 13:47:00) [5]

а про FreeNotification забыли ??


Anatoly Podgoretsky   (2005-03-16 13:35:00) [6]

Component1.Free;
Component2.Free;
...
ComponentN.Free;


Набережных С.   (2005-03-16 13:15:00) [7]

Нотификацию по-любому обрабатывать придется, чтобы в клиенте обнулить ссылку на сервер. Зачем лишнее делать?


PVOzerski   (2005-03-16 12:55:00) [8]

Есть у меня еще идейка... Если получится, расскажу :)


Набережных С.   (2005-03-16 12:54:00) [9]

Смотри Erik1 ©   (16.03.05 12:30) [3]. Механизм нотификации уже существует, достаточно в клиенте обрабатывать уведомления, и если уничтожается сервер, то закрывать соединение. Ну и регистрироваться, на случай размещения сервера и клиента в разных контейнерах. Если стандартный чем-то не устраивает - создай подобный свой.


PVOzerski   (2005-03-16 12:42:00) [10]

2TUser ©   (16.03.05 12:25) [1]
Нет, это не совсем то. Задача не как использовать в проекте "что есть", а как эти компоненты сами удачнее реализовать.

2VMcL ©   (16.03.05 12:28) [2]:
А потом такие клиенты назначать DataSet'ами всяким DB aware-контролам в design-time получится? Проверять долго :(


Erik1   (2005-03-16 12:30:00) [11]

Есть например при уничтожении сервера ты можеш затребовать уведомнения об этом. procedure Notification(AComponent: TComponent; Operation: TOperation); Установить это можно так:
procedure TAttribHolder.SetNotification;
var
 I: Integer;
 Component: TComponent;
begin
 for I := fAttribute.Count - 1 downto 0 do begin
   Component := TComponent(fAttribute[i].fComps);
   if Component <> nil then Component.FreeNotification(Self);
 end;
end;
И сделай все прощальные закрытия.


VMcL   (2005-03-16 12:30:00) [12]

>> [2]

Велик и могучая русский языка.

Исходный текст компонента-сервера доступен? Если, да, то я бы сделал по-другому. Не бросал "клиентов" на форму, а с помощью дизайнера, настраивал бы в их дизайн-тайме, как коллекцию клиентов компонента-сервера. Что-то вроде того, как сделано с колонками TListView.

?


VMcL   (2005-03-16 12:28:00) [13]

>> PVOzerski ©   (16.03.05 12:20)

Исходный текст компонента-сервера доступен? Если, да, то я бы сделал по-другому. Не бросал "клиентов" на форму, а с помощью дизайнера, определял бы в дизайн-тайме, как коллекцию клиентов компонента-сервера. Что-то вроде того, как сделано с колоноками TListView.

?


TUser   (2005-03-16 12:25:00) [14]

Первая мысль - в OnClose формы уничтожить все компоненты в правильном порядке.


Наверх

Титульная страница Поиск, карта сайта Написать письмо