Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.12;
Скачать: CL | DM;

Вниз

два потока. события, синхронизация   Найти похожие ветки 

 
Жека   (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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.022 c
15-1219647892
rx275d7_jedi
2008-08-25 11:04
2008.10.12
Написать программу


13-1121805388
NewWonder
2005-07-20 00:36
2008.10.12
C#: Borland or MS?


2-1220417936
TRSteep
2008-09-03 08:58
2008.10.12
Отправка почты


1-1199993925
kilonet
2008-01-10 22:38
2008.10.12
Создание отчёта


11-1194368147
XL007
2007-11-06 19:55
2008.10.12
Оффлайн справочник по библиотеке