![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Асинхронные сокеты "забивают" очередь сообщений
SpellCaster © (2008-04-01 17:01:00)Делаю класс асинхронного сокета и столкнулся с проблемкой зависания проги. Прога коннектится к серверу и начинает принимать от него непрерывный поток данных. Соответственно, после каждого Recv в очередь сразу же ставится следующее сообщение с событием FD_READ, которое тут же и обрабатывается. В итоге сообщения от главного окна просто не могут пробиться сквозь этот цикл. Вместе с тем, если запускать в начале процедуры SocketEvent Application.ProcessMessages, то все работает (естественно). Однако есть у меня сомнение: ведь эта процедура сразу вытаскивает из очереди очередное сообщение. Вполне вероятно, что это может оказаться следующая мессага от того же сокета - и тогда SocketEvent будет запущен второй раз, а уже после обработки этого сообщения управление вернется к первой копии SocketEvent. То есть, к примеру, может получиться так, что сначала обработается FD_CLOSE, а потом придет очередь FD_READ, что не очень-то здорово.
Поэтому хочу спросить у знатоков, есть ли какой-то хороший путь решения данной проблемы? Или, может, я зря волнуюсь насчет перепутывания сообщений? В идеале хотелось бы иметь способ вместо ProcessMessages обработать только мессаги формы, а потом уже с чистой совестью заниматься с сокетом.
Посмотрел сорсы ICS, там реализована собственная выборка собщений. В принципе, можно сделать так же, но я пока не разобрался, как ее применять.
В общем, если что посоветуете, буду рад... только два условия:
1) Не хочется юзать нити
2) Видеть реплики типа "Зачем тебе это надо" и "не занимайся ерундой" также не горю желанием.
Сергей М. (2008-04-16 11:27:00) [1]Если теряется, значит не устраивает.
SpellCaster (2008-04-16 10:39:00) [2]Да меня в принципе устраивает и последовательно, проблема-то в том, что за этим обслуживанием теряется возможность пользовательского интерфейса - окошко там переждвинуть, кнопку нажать.
Сергей М. (2008-04-14 16:58:00) [3]В одном потоке твои клиенты будут обслуживаться последовательно.
Если тебя это устраивает, делай в одном.
А потоки на то и придуманы, чтобы распараллелить длительные вычислительные алгоритмы, а не выполнять их последовательно.
SpellCaster (2008-04-14 16:46:00) [4]То есть "правильный курс"- это дополнительные потоки? И в одном потоке никак?
Сергей М. (2008-04-14 14:53:00) [5]
> большинтсво все-таки с гуем
Причем здей гуй ?
> уйдём от серваков. Возьмем "качалки" с кучей потоков загрузки
> - они-то не тормозят
И у тебя не будет "тормозить", если втанешь на "правильный курс".
> хочу узнать, какой там принцип юзается
Там транспортная и/или прикладная логика вынесена в дополнительные потоки.
> иначе смысл городить огород, легче все на синхронных оставить
Решать тебе.
SpellCaster (2008-04-14 13:36:00) [6]> Их по-другому делают
Вот я и хочу узнать, какой там принцип юзается. С нитями понятно, хотя все равно не хочется с ними дело иметь - иначе смысл городить огород, легче все на синхронных оставить...
SpellCaster (2008-04-14 13:34:00) [7]> Без окон
Может, есть и без окон, но большинтсво все-таки с гуем... виндоус все-таки. Ладно, уйдём от серваков. Возьмем "качалки" с кучей потоков загрузки - они-то не тормозят...
> Ты вон все апями озабочен да BeginThread'ами)
Вот не надо, треды через апи меня пока не привлекают)
> Ты же не озаботился исследованием, ты сразу ринулся код
> лепить)
> Еще и оффтопом меня попрекнул)
Гм. Исследованием чего?
Ну а насчет оффа - все-таки речь не о соксах, согласись.
Сергей М, (2008-04-10 20:19:00) [8]
> В каком смысле > созданы в его собственном контексте.? Функция
> CreateЦindow была вызвана внутри Execute?
Да.
Хотя каким боком к тебе этот Execute ?
Ты вон все апями озабочен да BeginThread'ами)
> если в том же Execute я организую выборку сообщений, то
> она будет распространяться только на эти окна?
По умолчанию - да.
> как-то же делают серваки с сотнями клиентов, которые
> не тормозят
Их по-другому делают.
Ты же не озаботился исследованием, ты сразу ринулся код лепить)
Еще и оффтопом меня попрекнул)
Чудо, блин)
DiamondShark (2008-04-10 20:09:00) [9]
> ну как-то же делают серваки с сотнями клиентов, которые
> не тормозят
Без окон
> и этот ICS все хвалили
ай да, конечно.
SpellCaster (2008-04-10 18:14:00) [10]Хотя мне все равно кажется, что это не выход... блин, ну как-то же делают серваки с сотнями клиентов, которые не тормозят... и этот ICS все хвалили, а там ведь такая же система
SpellCaster (2008-04-10 17:38:00) [11]В каком смысле > созданы в его собственном контексте.? Функция CreateЦindow была вызвана внутри Execute?
И тогда если в том же Execute я организую выборку сообщений, то она будет распространяться только на эти окна?
Сергей М. (2008-04-10 16:11:00) [12]Что "ну и" ?
SpellCaster (2008-04-10 16:06:00) [13]Ну и...?
Сергей М. (2008-04-10 14:19:00) [14]По умолчанию поток может выбирать сообщения только тем окнам, которые созданы в его собственном контексте.
SpellCaster (2008-04-10 12:59:00) [15]Выборку
Сергей М, (2008-04-09 20:31:00) [16]
> разве он не освобождается после закрытия?
Смотря с какой стороны его закрыть.
> как сделать это в отдельном потоке?
Сделать что?
Выборку ?
Обработку ?
И то и другое ?
SpellCaster (2008-04-09 18:15:00) [17]> Чтение-то не из сокета происходит, а из внутреннего буфера
> приема !
> Если там что-то имеется на момент закрытия сокета, то recv
> вернет это самое "что-то".
Ну да. Но разве он не освобождается после закрытия? К тому же хэндл уэ точно не будет иметь смысла после Close.
> Ты обработку с выборкой не путаешь ?
Угу... есть такое дело. Так как сделать это в отдельном потоке? Или там нужно будет PostThreadMessage юзать?
Сергей М. (2008-04-09 14:24:00) [18]
> Из закрытого сокета вроде как читать не получится
Чтение-то не из сокета происходит, а из внутреннего буфера приема !
Если там что-то имеется на момент закрытия сокета, то recv вернет это самое "что-то".
> 1)
Ты обработку с выборкой не путаешь ?
> 2)
Никак.
Да и нафих оно не нужно, потому что извращенная это логика.
Но если изврат твоя стихия, то можно извлекать из очереди сообщения, относящиеся только к твоим сокетам и тут же ставить их в хвост очереди сообщений безо всякой обработки.
SpellCaster (2008-04-09 14:10:00) [19]> С чего ты так уверен ?
Из закрытого сокета вроде как читать не получится...
Хорошо, тогда будет 2 вопроса:
1) Как организовать обработку событий сокета в отдельном потоке, потому что мессаги все равно ведь приходят в Application. Возможно, их надо фильтровать по коду мессаги?
2) Как насчет варианта вместо ProcessMessages сделать свой аналог, который будет извлекать из очереди только сообщения, не относящиеся к сокетам.
Сергей М. (2008-04-04 21:57:00) [20]
> Предложи альтернативный способ, я его с радостью рассмотрю
Альтернатив нет - сначала recv(), а потом выкрутасы.
Не нравится ?
Выноси транспорт с его событиями в доп.поток.
> пришедшие данные будут утеряны
С чего ты так уверен ?