Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.27;
Скачать: CL | DM;

Вниз

Как бы управлять порядком уничтожения компонентов?   Найти похожие ветки 

 
PVOzerski ©   (2005-03-16 12:20) [0]

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

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

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


 
TUser ©   (2005-03-16 12:25) [1]

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


 
VMcL ©   (2005-03-16 12:28) [2]

>>PVOzerski ©   (16.03.05 12:20)

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

?


 
Erik1 ©   (2005-03-16 12:30) [3]

Есть например при уничтожении сервера ты можеш затребовать уведомнения об этом. 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) [4]

>> [2]

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

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

?


 
PVOzerski ©   (2005-03-16 12:42) [5]

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

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


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

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


 
PVOzerski ©   (2005-03-16 12:55) [7]

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


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

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


 
Anatoly Podgoretsky ©   (2005-03-16 13:35) [9]

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


 
icWasya ©   (2005-03-16 13:47) [10]

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


 
PVOzerski ©   (2005-03-16 16:38) [11]

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


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

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


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

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


 
MalkoLinge ©   (2005-03-16 19:36) [14]

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



Страницы: 1 вся ветка

Текущий архив: 2005.03.27;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.248 c
1-1110800372
tex
2005-03-14 14:39
2005.03.27
Как заставить TImage сжать bmp-файл сохраняя пропорции


3-1109367926
kserg
2005-02-26 00:45
2005.03.27
есть поле со значениями -1,0,1,2,3.....и т.д.


1-1110960669
Rule
2005-03-16 11:11
2005.03.27
Скроллинг в Мемо


1-1110714441
Ji
2005-03-13 14:47
2005.03.27
Перевести из ASM в Delphi


4-1108623210
dak_brn
2005-02-17 09:53
2005.03.27
Управление ICQ клиентом из Delphi