Текущий архив: 2007.10.14;
Скачать: CL | DM;
Вниз
RemoteDataModule - не работает счетчик пользователей. Найти похожие ветки
← →
tytus © (2007-06-26 11:34) [0]В обработчике OnCreate такой код:
procedure TMaRDM.RemoteDataModuleCreate(Sender: TObject);
begin
with ServerFm do
UpdateUserCount(true);
end;
соответсвенно в форме ServerFm описана процедура:
public
{ Public declarations }
procedure UpdateUserCount(Fup:bool);
procedure TServerFm.UpdateUserCount(Fup:bool);
begin
if Fup then
inc(FCount)
else
dec(FCount);
SB1.Panels[0].Text:=IntToStr(FCount);//SB-TStatusBar
end;
Если заремить в OnCreate вызов процедуры UpdateUserCount - то все работает, ежели нет - то сервер и клиент виснут.
Как сие исправить?
В обработчике OnDestroy пишу:
procedure TMaRDM.RemoteDataModuleDestroy(Sender: TObject);
begin
with ServerFm do
UpdateUserCount(false);
end;
← →
Сергей М. © (2007-06-26 11:46) [1]
> Как сие исправить?
Например, вот так:
const
MYMESSAGE = WM_USER + 1000;
type
TServerFm = class(TForm)
..
procedure MsgUpdateUserCount(var Message: TMessage); message MYMESSAGE;
..
end;
..
procedure TServerFm.MsgUpdateUserCount(var Message: TMessage);
begin
UpdateUserCount(Boolean(Message.wParam));
end;
..
procedure TMaRDM.RemoteDataModuleCreate(Sender: TObject);
begin
with ServerFm do
SendMessage(WindowHandle, MYMESSAGE, Cardinal(True), 0);
end;
procedure TMaRDM.RemoteDataModuleDestroy(Sender: TObject);
begin
with ServerFm do
SendMessage(WindowHandle, MYMESSAGE, Cardinal(False), 0);
end;
← →
tytus © (2007-06-26 12:05) [2]>Сергей М. © (26.06.07 11:46) [1]
Не помогло...
← →
sniknik © (2007-06-26 12:14) [3]> то сервер и клиент виснут.
все что происходит в RemoteDataModule это отдельный процесс от основного, т.е. никаких прямых вызовов/ссылок на форму (VCL) и т.д.
по всем правилам надо с потоками работать.
> ... SendMessage ...
я бы поменял на PostMessage...
> Не помогло...
ну ты конечно все правильно сделал... ??? а Бил Гейтс виноват.
← →
tytus © (2007-06-26 12:24) [4]>sniknik © (26.06.07 12:14) [3]
PostMessage - ПОМОГЛО!
Спасибо Всем!
PS.
а Бил Гейтс виноват.
... а он во всем виноват -))))
← →
Сергей М. © (2007-06-26 12:46) [5]
> sniknik © (26.06.07 12:14) [3]
> я бы поменял на PostMessage
Что это меняет (кроме асинхронности), если передатчик и приемник в разных потоках ?
← →
Loginov Dmitry © (2007-06-26 13:09) [6]А кто мешает сделать FCount глобальной переменной?
И по-хорошем, не мешало бы защитить данную переменную (хотябы с помощью InterlockedIncrement) на случай многопоточной работы клиентских потоков в рамках сервера.
← →
ага (2007-06-26 14:26) [7]>Что это меняет (кроме асинхронности), если передатчик и приемник в разных потоках ?
Если tmApartment, то SendMessage главному потоку в RemoteDataModuleDestroy приведет к диадлоку
← →
Сергей М. © (2007-06-26 14:31) [8]
> ага (26.06.07 14:26) [7]
У автора "диадлок" происходит уже при создании, до уничтожения и дела не доходит.
← →
ага (2007-06-26 14:47) [9]Я про диадлок у автора ниче не видел, читал наверно невнимательно. Я на вопрос из [5] отвечал.
← →
Сергей М. © (2007-06-26 14:53) [10]
> читал наверно невнимательно
Ноги растут отсюда:
> Если заремить в OnCreate вызов процедуры UpdateUserCount
> - то все работает, ежели нет - то сервер и клиент виснут
Это однозначно говорит о том, что код RDM исполняется в контексте доп.потока
← →
ага (2007-06-27 06:07) [11]> Сергей М. ©
А, ну да, это я вчера по беспамятству спутал. В OnDestroy можно SendMessage пользовать, это в конструкторе нельзя. Factory.CreateInstance или как он там, ждет семафора, который освободится уже после завершения конструктора, а вызывается этот метод как правило из главной нити, тут и получаем диадлок. Ну и только при STA блокировка с главной нитью происходит, и если фабрика в главной нити создана и зарегина.
← →
Юрий Пасько (2007-08-01 14:54) [12]столкнулся с аналогичной проблемой. Решение такое -
1. создается обычный модуль данных (н-р dmAdmin), на него делается ссылка из RMD и из главной формы приложения сервера в разделе uses.
2. В этом модуле объявляется переменная н-р ClientsCount, можно создать ещё и список активных модулей типа TStringList
3. Эту переменную можно изменять напрямую из RDM или написать методы например dmAdmin.RegisterClient(DataModule : TRemoteDataModule) и
dmAdmin.UnRegisterClient(DataModule : TRemoteDataModule)
вызов этих методов размещается в процедурах создания и уничтожения модуля
4. Для получения информации о количестве клиентов в главной форме можно использовать либо метод (например по нажатию кнопки), либо создается поток, который с некоторой периодичностью опрашивает dmAdmin
Страницы: 1 вся ветка
Текущий архив: 2007.10.14;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.025 c