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

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

TIdTcpServer [D7, WinXP]


Страницы:   1 2

Ozone ©   (2004-04-22 09:46:00) 

Как при обработке события OnExecute сделать синхронизацию?

Пишу так

procedure Test;
begin
    {...}
end;

procedure TFServer.tcpServerExecute(AThread: TIdPeerThread);
begin
    {...}
    AThread.Synchronize(???);
    {...}
end;


И нужно ли это, если при обработке данного события необходимо выполнять достаточно длинные по времени действия?

Всем спасибо.


Digitman   (2004-04-22 14:38:00) [1]


> Я хочу через синхронайз вставить картинку в Image


совершенно необязательно использовать для этой цели  Synchronize

создай экз-р TImage прямо в своем потоке, заполни его как тебе нужно, а далее посылай форме при помощи PostMessage некое сообщение, параметром которого передай ссылку на свой экз-р TImage

при получении формой сообщения бери параметр, приводи его к типу TImage и выполняй ImageНаФорме.Assign(переданный_Image), после чего не забудь разрушить переданный параметром объект Image


Ozone   (2004-04-22 14:32:00) [2]

TO Digitman © [26]

Спаасибо. Попробую.


Digitman   (2004-04-22 14:30:00) [3]


> Пробовал так как задавал в вопросе - ошибку выдает
>
>
> AThread.Synchronize(Test);


ты хоть бы поинтересовался, О ЧЕМ КОНКРЕТНО говорит эта ошибка !

а говорит она о том, что Synchronize - защищенный метод класса TThread, и вызывать его допустимо только из методов наследников класса TThread (коим в дан.случае явл-ся TIdPeerThread)

ты же пытаешься вызвать защищенный метод отнюдь не не в методе класса TIdPeerThread, а в методе, являющемся обработчиком события OnExecute... обработчик же этот назначен у тебя, очевидно, как метод формы, на которую ты бросил IdTCPServer .. так что ж ты хочешь ?

для доступа к методу Synchronize ты должен создать класс-наследник TIdPeerThread, а чтобы можно было использовать экз-ры этого класса, ты должен написать и подключить собственный класс  TIdThreadMgr


Ozone   (2004-04-22 14:29:00) [4]

TO Reindeer Moss Eater © [24]

>> Ну и зачем весь длинный Test выполнять через Syncronize?

Я не говорил, что Test длинный. Я хочу через синхронайз вставить картинку в Image.

>> Все клиентские подключения имеют дело с одним и тем же Image?

Дело обстоит немного сложнее. Есть 4 картинки (экрана), т.е. сразу могут транслировать только четыре клиента. НО! То куда они транслируют (Image) изменяется в режиме run-time (а точнее сам юзверь говорит кому и куда класть свою картинку).


Reindeer Moss Eater   (2004-04-22 14:24:00) [5]

Ну и зачем весьдлинный Test выполнять через Syncronize?

И еще.
Все клиентские подключения имеют дело с одним и тем же Image?


Ozone   (2004-04-22 14:21:00) [6]

TO Reindeer Moss Eater © [22], [23]

Все я прекрастно понимаю.
Просто, т.к. я не мог синхронизировать мои AThread потоки с основным VCL-потоком, то сделал КС на доступ к Image, вот и все.

Теперь хочу отказаться от КС и сделать по человечески.


Reindeer Moss Eater   (2004-04-22 14:17:00) [7]

А как именно вызвать эту самую синхронизацию?

Синхронизацию кого с чем? Можешь внятно сказать?


Reindeer Moss Eater   (2004-04-22 14:15:00) [8]

Ты хоть немного пробуешь понять что такое Syncronize и что такое критическая секция? А главное стокилометровую разницу между ними?


Ozone   (2004-04-22 14:08:00) [9]

TO Digitman © [10]

>> вот здесь, вероятно, syncronize() может и понадобиться

А как именно вызвать эту самую синхронизацию?

Пробовал так как задавал в вопросе - ошибку выдает


AThread.Synchronize(Test);


А если я это все заделаю через КС - будет ли это хорошим тоном?


Verg   (2004-04-22 11:50:00) [10]


> Reindeer Moss Eater ©   (22.04.04 11:46) [18]
> Уж если ReadLN вызвал исключение то проверять соединение
> большого смысла нет.
> Можно смело заверщать обработку сессии клиента.


Не в этом дело, если остановка сервера произошла на readln, то и так все будет нормально.
А вот если это случилось на длительной (или зациклившейся) обработке принятой информации, при которой не производится проверки на целостность соединения, то как раз описываемый эффект и будет наблюдаться.


Reindeer Moss Eater   (2004-04-22 11:46:00) [11]

Уж если ReadLN вызвал исключение то проверять соединение большого смысла нет.
Можно смело заверщать обработку сессии клиента.


Verg   (2004-04-22 11:38:00) [12]


> Reindeer Moss Eater ©   (22.04.04 11:23) [15]
> Проверяй-непроверяй, но если возврата из ReadLN нет, то
> что толку?


При остновке сервера, его поток отключает все клиентские сокеты и пытается остановить все клиентские потоки. При отключении соединения ReadLn даст исключение, которое будет обработано в  TIdPeerThread.Run и приведет к остановке (завершению) клиентского потока.

Вот маленькая "модель":

Запустите сервер, потключитесь к его порту Telnet-ом и введите 15-20 сиволов плюс enter. После этого попытайтесь остановить сервер...

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var S : string;
   I : integer;
begin
   S:=AThread.Connection.ReadLn;
   for I:=1 to length(S) do
   begin
     S[I] := UpCase(S[I]);
     Sleep(1000);
     AThread.Connection.CheckForDisconnect; // Закометарив эту строку мы получим как раз Terminate Thread Timeout если попытаемся остановить сервер во время обработки строки клиентским потоком
   end;
end;


Ozone   (2004-04-22 11:37:00) [13]

Хорошо, спасибо, попробую что-нить сделать.

И еще вопрос - может момно как-нибудь отловить исключение, возникающеся по истечению времени TimeOut'a?


Reindeer Moss Eater   (2004-04-22 11:23:00) [14]

Проверяй-непроверяй, но если возврата из ReadLN нет, то что толку?


Verg   (2004-04-22 11:22:00) [15]


> Ozone ©   (22.04.04 11:16) [11]


Если в этом методе (tcpServerExecute) "закручивается" долгая оперция, например с циклом там или еще чего, то нужно хотя бы изредка проверять состояние соединеия по ходу выполнения этой операции.


Ozone   (2004-04-22 11:21:00) [16]

TO Reindeer Moss Eater ©[12]

А как этого избежать?


Reindeer Moss Eater   (2004-04-22 11:19:00) [17]

Твои методы чтения/записи выполняются с бесконечным таймаутом.
Вот и вся причина


Ozone   (2004-04-22 11:16:00) [18]

TO Digitman ©[9]

>> данная ошибка же возникает по совершенно иным причинам

Тогда не понятно почему - все остальное сделано вроде по аналогии с упомянутым выше примером???


Digitman   (2004-04-22 11:12:00) [19]


> Ozone


конечно же, если ты влупил какой-то код в OnExecute в рамки синхронизации, то такая вот ситуация вполне может и иметь место : доп.поток ждет , когда указанный метод будет выполнен осн.потоком, а последний в этот момент (в обработчике, например, кнопки, где ты деактивируешь сервер) взвел Terminated и ждет, когда доп.поток завершится ..

получается замкнутый круг - "Ванька ждет Маньку, а Манька ждет Ваньку"


Digitman   (2004-04-22 11:08:00) [20]


> <кое-что выводим на экран>


вот здесь, вероятно, syncronize() может и понадобиться

все остальное, скорей всего, обойдется безо всякой синхронизации

данная ошибка же возникает по совершенно иным причинам, никак не связанным с наличием или отсутствием синхронизации - период тайм-аута ожидания приема данных как минимум не должен быть INFINITE, иначе поток не сможет опрашивать флаг Terminated, взводимый сервером при принудительной его деактивации


Страницы:   1 2

Наверх

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