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