-
пишу компонент реализующий протокол взаимодействия с сервером. при подключении компонент создает ещё один поток в котором принимает команды от сервера. при получении команды поток вызывает Synchronize(parse). в методе parse происходит обработка команды и вызов соответствующих обработчиков событий. все бы ничего за вот понадобилось в компоненте реализовать функцию которая бы отправляла на сервер некоторый запрос и возврашала управление ->
-
только при получении ответа от сервера на этот запрос. я попробовал реализовать эту схему используя event и waitforsingleobject но так как парсинг происходит в главном потоке программа зависает. есть ли варианты решения этой ситуации. заранее пасипа! :)
-
Странное желание. Ты, пытаясь избавиться от блокировки основного потока сетевыми функциями, создаешь доп поток и потом хочешь обратно получить блокировку. Получив эту блокировку - ты жалуешься что программа зависает :) Ты уж реши что тебе важнее.
-
> Странное желание. Ты, пытаясь избавиться от блокировки основного
> потока сетевыми функциями, создаешь доп поток и потом хочешь
> обратно получить блокировку. Получив эту блокировку - ты
> жалуешься что программа зависает :) Ты уж реши что тебе
> важнее.
Компонент действительно должен иметь возможность блокирующих и неблокирущих вызовов сетевых функций. Но так как используется отдельный поток для чтения команд, я не могу использовать SendCmd. В результате планирую получить что-то вроде: function TMegaComponent.SendPacket(Cmd: string; Params: array of string; Blocked: Boolean{если да то поток замораживается до прихода ответа}): TCmd;
P.S. Утром пришла идея делать проверку в слушающем потоке перед передачей упревления в Synchronize:
if MainThread.IsSleeped then
begin
if RecvedCmd = WaitedCmd then
begin
SetEvent(Event);
while Buffer.Count > 0 do
begin
Cmd := Buffer[0];
Synchronize(Parse);
end;
end else
begin
AddToBuffer(Cmd);
end;
end else
begin
Synchronize(Parse);
end;
Можт в чёт-то ошибся, но общая идея такая
-
А зачем парсить-то в главном? В главнный поток надо посылать уже готовые команды и события.
-
И это не надо, в главном потоке делать только отрисовку и если более одного потока и они нуждаются в синхронизации, то события синхронизации.
-
> А зачем парсить-то в главном? В главнный поток надо посылать
> уже готовые команды и события.
Т.е.? я ведь не могу вызывать обработчики событий прямо из слушающего потока, т.к. в них может быть потоконебезопасный код. Или я неправильно вас понял.
> И это не надо, в главном потоке делать только отрисовку
> и если более одного потока и они нуждаются в синхронизации,
> то события синхронизации.
У меня только один поток, я просто не могу понять как мне вызвать обработчики событий так, чтобы непроизошло конфликтов. А вообще я взял за основу исходник компонента TIRQ у него это реализованно именно так (весь парсинг происходит в VCL-потоке)
-
> Жека (02.11.2007 12:52:06) [6]
А у Арханлеьского вся обработка вообще проходит в основном потоке и что? Разве это примеры для подражания.
-
> Anatoly Podgoretsky © (02.11.07 13:15) [7]
Но какие минусы в этой системе, это ведь не серверная часть, в которой распаралеливание действительно может дать прирост производительности и сделать программу более стабильной. Слушающий поток создан только для того чтобы интерфейс не замораживался. Если действительно существуют весомые причины для того, чтобы парсинг производить в отдельном потоке, то как мне вызывать обработчики событий? каждый раз сохранять параметы обработчика в переменных потока после чего вызывать Synchronize(OnCmd1) ? мне кажется это излишняя громоздкость. или я ошибаюсь?
-
Размораживание интерфейса надо делать через Application.ProcessMessages, а при работе с сетью использовать ассинхронные методы работы. Потоки не для того.
-
Я уже написал значительную часть проекта используя Indy, там не предусмотрена асинхронность
-
> Жека (02.11.2007 14:57:10) [10]
Знаешь я написал целый проект, но это не остановило меня от перехода на ICS
-
Чтожь, видно меня ждёт море работы, спасибо за совет.
-
> Потоки не для того.
а для чего? прекрасно можно и индейцев в поток запихать)
-
автор> Слушающий поток создан только для того чтобы интерфейс не замораживался.
АП> Размораживание интерфейса надо делать через Application.ProcessMessages
Потоки созданы не для размораживания интерфейса, а для паралельного исполнения задач. Хотя любой микроскоп можно использовать и не по назначению, но это говорит об отсутствии должной квалификации.