Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
Вниз
два потока. события, синхронизация Найти похожие ветки
← →
Жека (2007-11-01 20:28) [0]пишу компонент реализующий протокол взаимодействия с сервером. при подключении компонент создает ещё один поток в котором принимает команды от сервера. при получении команды поток вызывает Synchronize(parse). в методе parse происходит обработка команды и вызов соответствующих обработчиков событий. все бы ничего за вот понадобилось в компоненте реализовать функцию которая бы отправляла на сервер некоторый запрос и возврашала управление ->
← →
Жека (2007-11-01 20:35) [1]только при получении ответа от сервера на этот запрос. я попробовал реализовать эту схему используя event и waitforsingleobject но так как парсинг происходит в главном потоке программа зависает. есть ли варианты решения этой ситуации. заранее пасипа! :)
← →
DVM © (2007-11-01 23:48) [2]Странное желание. Ты, пытаясь избавиться от блокировки основного потока сетевыми функциями, создаешь доп поток и потом хочешь обратно получить блокировку. Получив эту блокировку - ты жалуешься что программа зависает :) Ты уж реши что тебе важнее.
← →
Жека (2007-11-02 07:09) [3]
> Странное желание. Ты, пытаясь избавиться от блокировки основного
> потока сетевыми функциями, создаешь доп поток и потом хочешь
> обратно получить блокировку. Получив эту блокировку - ты
> жалуешься что программа зависает :) Ты уж реши что тебе
> важнее.
Компонент действительно должен иметь возможность блокирующих и неблокирущих вызовов сетевых функций. Но так как используется отдельный поток для чтения команд, я не могу использовать 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;
Можт в чёт-то ошибся, но общая идея такая
← →
Reindeer Moss Eater © (2007-11-02 09:16) [4]А зачем парсить-то в главном? В главнный поток надо посылать уже готовые команды и события.
← →
Anatoly Podgoretsky © (2007-11-02 09:25) [5]И это не надо, в главном потоке делать только отрисовку и если более одного потока и они нуждаются в синхронизации, то события синхронизации.
← →
Жека (2007-11-02 12:52) [6]
> А зачем парсить-то в главном? В главнный поток надо посылать
> уже готовые команды и события.
Т.е.? я ведь не могу вызывать обработчики событий прямо из слушающего потока, т.к. в них может быть потоконебезопасный код. Или я неправильно вас понял.
> И это не надо, в главном потоке делать только отрисовку
> и если более одного потока и они нуждаются в синхронизации,
> то события синхронизации.
У меня только один поток, я просто не могу понять как мне вызвать обработчики событий так, чтобы непроизошло конфликтов. А вообще я взял за основу исходник компонента TIRQ у него это реализованно именно так (весь парсинг происходит в VCL-потоке)
← →
Anatoly Podgoretsky © (2007-11-02 13:15) [7]> Жека (02.11.2007 12:52:06) [6]
А у Арханлеьского вся обработка вообще проходит в основном потоке и что? Разве это примеры для подражания.
← →
Жека (2007-11-02 13:31) [8]
> Anatoly Podgoretsky © (02.11.07 13:15) [7]
Но какие минусы в этой системе, это ведь не серверная часть, в которой распаралеливание действительно может дать прирост производительности и сделать программу более стабильной. Слушающий поток создан только для того чтобы интерфейс не замораживался. Если действительно существуют весомые причины для того, чтобы парсинг производить в отдельном потоке, то как мне вызывать обработчики событий? каждый раз сохранять параметы обработчика в переменных потока после чего вызывать Synchronize(OnCmd1) ? мне кажется это излишняя громоздкость. или я ошибаюсь?
← →
Anatoly Podgoretsky © (2007-11-02 14:11) [9]Размораживание интерфейса надо делать через Application.ProcessMessages, а при работе с сетью использовать ассинхронные методы работы. Потоки не для того.
← →
Жека (2007-11-02 14:57) [10]Я уже написал значительную часть проекта используя Indy, там не предусмотрена асинхронность
← →
Anatoly Podgoretsky © (2007-11-02 15:10) [11]> Жека (02.11.2007 14:57:10) [10]
Знаешь я написал целый проект, но это не остановило меня от перехода на ICS
← →
Жека (2007-11-02 15:34) [12]Чтожь, видно меня ждёт море работы, спасибо за совет.
← →
MetalFan © (2007-11-05 11:47) [13]
> Потоки не для того.
а для чего? прекрасно можно и индейцев в поток запихать)
← →
Anatoly Podgoretsky © (2007-11-05 11:58) [14]автор> Слушающий поток создан только для того чтобы интерфейс не замораживался.
АП> Размораживание интерфейса надо делать через Application.ProcessMessages
Потоки созданы не для размораживания интерфейса, а для паралельного исполнения задач. Хотя любой микроскоп можно использовать и не по назначению, но это говорит об отсутствии должной квалификации.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.057 c