Форум: "Базы";
Текущий архив: 2002.07.04;
Скачать: [xml.tar.bz2];
Внизmidas Найти похожие ветки
← →
oss (2002-06-10 12:21) [0]У меня появилась проблема при старте мидас сервера.
А именно, на создание удаленного модуля стоит код, как в книжке :)
f_main.Label2.Caption:=IntToStr(StrToInt(f_main.Label2.Caption)+1);
Так, вот если его убрать, то клиет конектится без проблем,
если он есть, то клиент зависает, а сервер его не показывает,
хотя BSS видит клиета
← →
Digitman (2002-06-10 12:25) [1]в доп.потоке этого делать нельзя.
← →
oss (2002-06-10 12:35) [2]так ведь работало уже, и я не делаю разных потоков
← →
Digitman (2002-06-10 13:22) [3]Не знаю уж , что у тебя там работало, но, если приведенная тобой строчка стоит в обработчике любого из методов/событий (включая constructor/destructor) объекта RemoteDataModule, отдельный экземпляр которого в отдельном доп.потоке создается ядром BSS при коннекте клиента, то это работать не будет !
Проверь это сам и убедись, вставив перед этой строчкой вот такую строчку :
if GetCurrentThreadId = MainThreadId then
ShowMessage("Основной поток, работа с канвой безопасна")
else
ShowMessage("Доп.поток, работа с канвой небезопасна !")
← →
oss (2002-06-10 13:52) [4]Так создается же не f_main , а сам модуль !
← →
oss (2002-06-10 13:53) [5]И как тогда сделать чтобы работало ?
← →
Digitman (2002-06-10 14:09) [6]Правильно. Модуль создается. И создается он в доп.потоке. И в этом самом доп.потоке ты пытаешься изменить некое св-во некоего объекта, в процессе чего происходит обращение к API-ф-циям GDI32, и , как следствие, COM-сервер "виснет".
Посему нужна синхронизация обращения к GDI из доп.потока. Вместо непосредственного обращения к тому же f_main.Label2.Caption посылай своей форме f_main параметрическое сообщение любым удобным тебе способом (SendMessage, PostMessage), а уж форма, получив и обрабатывая сообщение в ОСНОВНОМ потоке, пишет чего-то там в свой label или еще куда-то.
← →
oss (2002-06-10 14:37) [7]возможно это метод, но тогда почему при отключении клиента сервер
отлавливает его и у меньшает занчение
f_main.Label2.Caption:=IntToStr(StrToInt(f_main.Label2.Caption)-1);
Тут же тоже разные потоки
← →
Polevi (2002-06-10 14:50) [8]вот тебе код BSS - твой датамодуль создается именно в этом потоке.
Synchronize(AddClient);
Synchronize(RemoveClient);
- именно таким образом надо работать с VCL - обращаться к компонентам из основного потока.
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil);
try
Synchronize(AddClient);
FTransport := CreateServerTransport;
try
Event := FTransport.GetWaitEvent;
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
GetInterface(ISendDataBlock, Obj);
if FRegisteredOnly then
FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else
FInterpreter := TDataBlockInterpreter.Create(Obj, "");
FInterpreter.FAppServer2:=FAppServer2;
FInterpreter.FClientID:=Integer(self);
try
Obj := nil;
if FTimeout = 0 then
WaitTime := INFINITE else
WaitTime := 60000;
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of
WAIT_OBJECT_0:
begin
WSAResetEvent(Event);
Data := FTransport.Receive(False, 0);
if Assigned(Data) then
begin
FLastActivity := Now;
FInterpreter.InterpretData(Data);
Data := nil;
FLastActivity := Now;
end;
end;
WAIT_OBJECT_0 + 1:
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
begin
if msg.message=WM_QUIT then FTransport.Connected := False
else
if msg.message=WM_SEND_SCRIPT_TO_CLIENT then FInterpreter.FCallbackObject.ExecScript(ClientScript) else
DispatchMessage(msg);
end;
WAIT_TIMEOUT:
if (FTimeout > 0) and ((Now - FLastActivity) > FTimeout) then
FTransport.Connected := False;
end;
except
FTransport.Connected := False;
end;
finally
FInterpreter.Free;
FInterpreter := nil;
end;
finally
FTransport := nil;
end;
finally
CoUninitialize;
Synchronize(RemoveClient);
end;
end;
← →
Digitman (2002-06-10 14:50) [9]Да о каком еще "отключении" идет речь-то ? Клиент-то твой "повис" !!! Он еще не подключился даже к AppServer"у корректно (потому как тот сам "завис" по указанной выше причине), а ты уже говоришь об отключении...
Еще раз повторяю : при возникновении похожих "непонятных" тебе ситуаций перед ЛЮБЫМ обращением из кода объекта RemoteDataModule к методам/свойствам визуальных объектов главной формы COM-сервера делай проверку на равенство GetCurrentThreadId = MainThreadId. Если условие равенства не выполняется, ни в коем случае нельзя делать такие обращения непосредственно ! Без синхронизации с осн.потоком это недопустимо и неверно !
← →
oss (2002-06-10 20:43) [10]1. проблему решил :)
х.з. почему но когда я убрал у лейбла выравнивание, оно было влево,
то все стало работать !
2. по поводу отключения, если я не делал того чтобы отслеживать сколько подключилось,
т.е коментировал строку
f_main.Label2.Caption:=IntToStr(StrToInt(f_main.Label2.Caption)+1),
то клиент не вис, и не егшо отключение отрабатывала
f_main.Label2.Caption:=IntToStr(StrToInt(f_main.Label2.Caption)-1)
и все ок.
3. Но всер авно Огромное спасибо за помошь,
тем более что есть над чем подумать. Спасибо
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.07.04;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c