![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TSocketConnection - познее связывание - - в другом потоке. [D7, WinXP]
tytus © (2007-07-03 10:22:00)Доброго дня мастера. Вот собственно и тема - хочу выполнять методы сервера в отдельном потоке+показать форму выполнения.
В главном приложении есть TSocketConnection (Connect1) и TClientDataSet (CDS1).
В конструкторе потока передаю и Connect1 и CDS1.
...
Constructor WaitThread.Create(AConnect:TSocketConnection;ADataSet:TClientDataSet);
begin
FConnect:=AConnect;
FDataSet:=ADataSet;
inherited create(false);
end;
procedure Execute;
begin
FConnect.AppServer.МойМетод;
end;
вот на такой код делфи ругаеццо:EVariantInvalidArgError,
а если запускать екзешник - то Error reading from Socket.
Как правильно сие сделать...
ага (2007-07-06 11:50:00) [1]>tytus © (06.07.07 11:25) [43]
это не про меня - надеюсь...
Да ты че, канечно НЕТ:) Ты-то как раз хорошо вопрос задал, грамотно, зато некоторые начали к буковам придетса типа "не ту кодировку использовал". Хотя абсолютно ясно было о чем речь.
tytus (2007-07-06 11:25:00) [2]>Сергей М. © (06.07.07 11:12) [42]
Можешь не отключать.
Но тогда тебе придется передавать в доп.поток неподключенный SocketConnection.
Для моего случая не подходит. Поясню в 2-х словах.
Клиент подключаеться к серверу вызовом метода Login, в который передается IP и Имя пользователя в системе.
Клиент должен оставаться подключенным чтобы работать далее с прогой.
Вызов метода Login происходит в OnAfterConnect ком-та TSocketConnection.
Получаеццо, если передавать в поток НЕподключенный Sock..ion , а в потоке подключаться - то плохо получится..-))
В любом случае - ОГРОМЕННОЕ спасибо что уделили мне внимание..
>ага
А остальные нудуют щеки и пытаются сделатьхорошую мину и при плохой игре- это не про меня - надеюсь... я вопрошаю по незнанию, за сим полагаюсь на Вашу милость, и выпендриваться не смею...
Меня интересует новый Question - сейчас напишу в новой ветке.
Сергей М. (2007-07-06 11:12:00) [3]
> tytus © (06.07.07 09:19) [40]
> SupportCallBacks нужна атключать
Можешь не отключать.
Но тогда тебе придется передавать в доп.поток неподключенный SocketConnection.
ага (2007-07-06 09:34:00) [4]>Сергей М. © (06.07.07 09:09) [39]
Предлагаю прекратить дальнейший "спор" за полной бессмысленностью.
:)))) А какой спор-то? Кто-то кому-то объяснил работу механизма - все, никакого спора нетути:) Вежливые люди за ето спасибо говорят ну иль хотяб свою ошибку признают. А остальные нудуют щеки и пытаются сделатьхорошую мину и при плохой игре. Наверно думают что все вокруг тупые и не поймут что к чему:))
tytus (2007-07-06 09:19:00) [5]БОЛЬШОЕ спасибо господа,
но я ужо и сам допер, чта SupportCallBacks нужна атключать.
Да и к тому-жо на клиенте всего адин дополнительный поток.
TWaitThread=class(TTHread)
FConnect:TSocketConnection;
...
constructor TWaitThread.Create(AConnect:TSocketConnection...);
begin
FConnect:=AConnect;
...
inherited Create(false);
end;
procedure TWaitThread.Execute;
begin
FConnect.AppServer.MyMethod(MyParams);
...
end;
Все работает как нужна!!
Есще раз - благодарствую...!!
end;
Сергей М. (2007-07-06 09:09:00) [6]
> чего тут непонятного?
Мне всепонятно.
Предлагаю прекратить дальнейший "спор" за полной бессмысленностью.
ага (2007-07-06 08:47:00) [7]"Пока не поступают обратные вызовы, логика транспорта в этой нити принципиально ничем не отличается от логики транспорта в осн.нити - те же блокирующие вызовы send и recv, те же последовательные "двойки" из отправки CallSig-дейтаблока и ожидания/приема соответствующего ему ResultSig-дейтаблока. Все синхронно: запрос-ответ, запрос-ответ..."
Ты че исходники не смотрел что-ли? Какие нафиг двойки?:) Лана, с сюда скопирую.
Вот так коннект открывается.
procedure TStreamedConnection.InternalOpen;
begin
if FSupportCallbacks then
begin
FTransport := TTransportThread.Create(Handle, CreateTransport);
FTransport.OnTerminate := TransportTerminated;
WaitForSingleObject(FTransport.Semaphore, INFINITE);
end else
begin
FTransIntf := CreateTransport;
FTransIntf.SetConnected(True);
end;
end;
По барабану будет кто пользоваться каллбэками али нет, все одно транспортный трэд запускается ежли FSupportCallbacks установлен, а устанавливается он в конструкторе.
А вот так с пакетами клиент работает
function TStreamedConnection.Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock;
var
Msg: TMsg;
Context: Integer;
begin
if FSupportCallbacks then
begin
if not Assigned(FTransport) then Exit;
Data._AddRef;
PostThreadMessage(FTransport.ThreadID, THREAD_SENDSTREAM, Ord(WaitForResult),
Integer(Pointer(Data)));
if WaitForResult then
while True do
begin
if GetMessage(Msg, FHandle, THREAD_RECEIVEDSTREAM, THREAD_EXCEPTION) then
begin
if Msg.message = THREAD_RECEIVEDSTREAM then
begin
Result := IDataBlock(Msg.lParam);
Result._Release;
if (Result.Signature and ResultSig) = ResultSig then
break else
Interpreter.InterpretData(Result);
end
else if Msg.Message WM_NULL then
DoError(Exception(Msg.lParam))
else
raise Exception.CreateRes(@SReturnError);
end else
raise Exception.CreateRes(@SReturnError);
end
else
GetMessage(Msg, FHandle, THREAD_SENDNOTIFY, THREAD_SENDNOTIFY);
end else
begin
if not Assigned(FTransIntf) then Exit;
Context := FTransIntf.Send(Data);
Result := FTransIntf.Receive(WaitForResult, Context);
end;
if Assigned(Result) and ((Result.Signature and asMask) = asError) then
Interpreter.InterpretData(Result);
end;
Смотрящий да увидит:) Ежли в истине стоит FSupportCallbacks - усë, пакеты пошли через транспортную нить. А куда же ента нить ответ отправит? А вот куда!
if GetMessage(Msg, FHandle, THREAD_RECEIVEDSTREAM, THREAD_EXCEPTION)
А чеж эт за FHandle такой? Дык вот же он, в InternalOpen
FTransport := TTransportThread.Create( Handle, CreateTransport);
Вот здесь-то он зараза и создается. И че ж получается? А то что ответ пойдет в тот трэд в котором окно FHandle создавали, то бишь откуда коннект открывали. Если в главном потоке открывали то в главный и пойдет. А он про ентот запрос знать не знает и ведать не ведает:)
И чего тут непонятного?
Сергей М. (2007-07-06 08:20:00) [8]
> Если TSocketConnection.SupportCallbacks установлен в истину
> то для обмена с серваком запускается дополнительная нитка
Ну и что ?
Пока не поступают обратные вызовы, логика транспорта в этой нити принципиально ничем не отличается от логики транспорта в осн.нити - те же блокирующие вызовы send и recv, те же последовательные "двойки" из отправки CallSig-дейтаблока и ожидания/приема соответствующего ему ResultSig-дейтаблока. Все синхронно: запрос-ответ, запрос-ответ...
Просто при разрешенных колбэках та самая доп.нить способна при ожидании ответа на запрос принять и диспетчеризовать встречный запрос, в то время как при запрещенных колбэках любй встречный запрос расценивается как исключение.
ага (2007-07-06 06:51:00) [9]"Не без оснований смею предполагать, что автор знать об этом ничего не знает и никакими колбэками в его аппсервере не пахнет."
Ага. Потому он еë и оставил в истине:))
ага (2007-07-06 06:49:00) [10]"Это ничего не меняет, если серверная сторона не пытается задействовать эту потенциальную возможность клиента."
По барабану использует или нет. Если TSocketConnection.SupportCallbacks установлен в истину то для обмена с серваком запускается дополнительная нитка, хош используй хош не используй. И на этом усë, фишка из вопроса пахать не будет. Глянь TStreamedConnection.Send
Сергей М. (2007-07-05 13:46:00) [11]
> Он по умолчанию включен
Это ничего не меняет, если серверная сторона не пытается задействовать эту потенциальную возможность клиента.
Не без оснований смею предполагать, что автор знать об этом ничего не знает и никакими колбэками в его аппсервере не пахнет.
ага (2007-07-05 13:34:00) [12]>> ежели каллбак разрешен то полный обломс
>Про этот режим и речи не идет
Как эт не идет? Ишшо как идет. Он по умолчанию включен а штоб отключал кто - о том ни слова. Значить о нем и речь:)) И ошибка в вопросе как раз с той оперы.
Сергей М. (2007-07-05 12:21:00) [13]
> ежели каллбак разрешен то полный обломс
Про этот режим и речи не идет.
> Ежли без обраток то типа можно, но шибко осторожно, ниче
> другого делать с коннектом походу в ето время нельзя
Ну а вот это уже ближе к телу)
Собственно из объяснений автора как раз и не следует то, что он во время работы доп.треда с коннектом делает с этим же коннектом что-то еще в другом треде. Ну а раз так, то ничего криминального в его действиях покане наблюдается.
ага (2007-07-04 11:27:00) [14]Ага, значит глянул я исходники освежил:)
Вобщем ежели каллбак разрешен то полный обломс, ответ от сервака придет в майн поток или где коннекшен открывали, а там ево не ждуть:) Вот ето я видать и помнил. Ежли без обраток то типа можно, но шибко осторожно, ниче другого делать с коннектом походу в ето время нельзя. То бишь паралельности один фиг не получим.
ага (2007-07-04 09:40:00) [15]2 Сергей М. ©
Слушай, ну я давно ужо с етим разбирался и щас опять вспоминать мне времени нетути. Я ж не говорю что я носитель верховной истины:) Может ты и прав. Просто покажи код, коротенько так, строк на двадцать. Типа передаем в нить открытый сокетКоннекшен и в ните дергаем какой-нить метод сервера с одним параметром.
Ну иль я попожже все таки освежу в памяти енто дело.
Сергей М. (2007-07-04 09:09:00) [16]
> ага
Ничто не мешает маршаллеру исполнение акций asCreateObject и asFreeObject в одном треде, а акций asInvoke для этого объекта - в другом треде. Естетственно при условии, что в момент существования объекта ни один третий тред не прикажет маршаллеру исполнить акцию asCreateObject или asFreeObject - в этом случае результат конечно же будет плачевный.
Сергей М. (2007-07-04 08:41:00) [17]
> чего именно мне там смотреть?
Конкретно взаимодействие методов
TStreamedConnection.Send
и
TTransportThread.Execute
ага (2007-07-03 17:38:00) [18]Хе:) И чего именно мне там смотреть? Насмотрелся ужо.
Я так понял, что кода, подтверждающего сказанное в [4], не будет? Я так и думал.
Сергей М. (2007-07-03 15:29:00) [19]
> ага (03.07.07 14:43) [24]
Смотри исходники.
ага (2007-07-03 14:45:00) [20]А еще он кажись отдельный поток создает для собсно связи но ето я точно не помню