powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / В каких случаях вы используете метод TThread.Queue?
21 сообщений из 46, страница 2 из 2
В каких случаях вы используете метод TThread.Queue?
    #39976532
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне удалось собрать всю необходимою информацию для того, чтобы продолжить своё занятие в отпуск. Разобрался, как использовать Queue для организации надежной передачи данных в основной поток без использования дополнительных списков (пришлось таки поставить современную Delphi с поддержкой Queue и поэкспериментировать с анонимными процедурами :). Удалось подготовить наглядный пример, который показывает все аспекты работы Queue.
Всем спасибо за участие!
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976565
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad F
Dmitry Arefiev,

Единственное, что в этом зажигательном спиче показалось интересным, так это "почти не вызовет".
Прошу пояснить.))
В консольных проектах механизм Synchronize/Queue вообще не будет работать от слова совсем (если ты сам вручную в каком-нибудь цикле не будешь обрабатывать накопившийся список вызовов, вызывая CheckSynchronize).
По тем же причинам Synchronize/Queue на работают в dll.
По тем же причинам Synchronize/Queue на работают нигде до вызова Application.Run.
А из-за костыля, который лечит дедлоки этого механизма, вызов метода TThread.WaitFor (а он вызывается и в деструкторе) в главном потоке - грузит проц на 100%.
В общем, Synchronize/Queue - это то, чего не надо было делать в Delphi и использовать тоже.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976576
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

Со всем этим не спорю, но тогда так и надо прямо писать.
А то получается как "немного беременна".
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976614
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
rgreat
Queue вообще не является способом передачи данных, это способ выполнения кода в главном потоке.


В официальной документации про Queue практически ничего нет. Зачем его делали - непонятно. Synchronize - является способом передачи данных в основной поток, SendMessage, PostMessage - являются. А вот Queue - не является.
если бы VCL не писали криворукие, может быть и работало бы SendMessage, PostMessage нормально. Но чуть тронешь в их обработчике гуи, то может быть конкретный пипец

SendMessage, PostMessage - рождает кучу трудноуловимых багов в VCL. По тем проектам, на которые я попадал, я только за этот год поймал и пофиксил около 3-х багов ими вызванных

первоначально, как только массово вошла в эксплуатацию 10-ка, этих багов было вообще пруд пруди
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976637
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
В каких случаях Вы используете метод TThread.Queue и почему?
Dmitry Arefiev
Последнее подходит для каких-либо прогрессов выполнения
я в частности для этого
DmSer
В случае PostMessage мы может передавать данные через wParam и lParam, мы имеем полный контроль над своей программой. В случае Queue нет никаких wParam и lParam
но все что нужно можно запихать в собственный враппер использующий механизм Queue/StaticQueue
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976673
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavan
но все что нужно можно запихать в собственный враппер использующий механизм Queue/StaticQueue
архитектурно это самый хороший путь, если есть такая возможность
локализованный код легче исправить и отладить

а то на KiUserCallbackDispatcher в багрепортах уже глаз дёргать начинает
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976898
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
если бы VCL не писали криворукие, может быть и работало бы SendMessage, PostMessage нормально. Но чуть тронешь в их обработчике гуи, то может быть конкретный пипец

SendMessage, PostMessage - рождает кучу трудноуловимых багов в VCL. По тем проектам, на которые я попадал, я только за этот год поймал и пофиксил около 3-х багов ими вызванных
А можно пару примеров этой кучи?
А то я чото правда не могу придумать, использовал всегда и горя не знал.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976919
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
kealon(Ruslan)
если бы VCL не писали криворукие, может быть и работало бы SendMessage, PostMessage нормально. Но чуть тронешь в их обработчике гуи, то может быть конкретный пипец

SendMessage, PostMessage - рождает кучу трудноуловимых багов в VCL. По тем проектам, на которые я попадал, я только за этот год поймал и пофиксил около 3-х багов ими вызванных
А можно пару примеров этой кучи?
А то я чото правда не могу придумать, использовал всегда и горя не знал.
пишу по памяти, вот основные ошибки которые возникают:
  • Canvas don't allow drawing
  • An OS function failed
  • Control has no parent
  • иногда просто изменение Visible не срабатывает
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976946
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

Не видел такого никогда.. А как добиться этих ошибок с помощью Post/SendMessage?
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976957
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,
Такие ошибки возникают, когда программист не может правильно реализовать синхронизацию с основным потоком VCL. И это не зависит от Send/Postmessage или Synchronize.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976958
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
kealon(Ruslan),

Не видел такого никогда.. А как добиться этих ошибок с помощью Post/SendMessage?
как бы передо мной всегда обратная задача стоит, специально не вызывал такое

ваш софт багрепорты делает? (EurekaLog, Madshi)

вот, например, причина "Canvas don't allow drawing"

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure TGraphicControl.WMPaint(var Message: TWMPaint);
begin
  if (Message.DC <> 0) and not (csDestroying in ComponentState) then
  begin
    Canvas.Lock;
    try
      Canvas.Handle := Message.DC;
      try
        Paint;
      finally
        Canvas.Handle := 0;  <<<<---- какой дэбил догадался это написать?
      end;
    finally
      Canvas.Unlock;
    end;
  end;
end;

...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39976970
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan), А что тут не устраивает? Девайс контекст после вызова процедуры станет невалидным, его таким и помечают.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977024
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский Борис
kealon(Ruslan), А что тут не устраивает? Девайс контекст после вызова процедуры станет невалидным, его таким и помечают.
здесь нет защиты от неявной рекурсии - а SendMessage, PostMessage её могут вызвать, помним про KiUserCallbackDispatcher?

старый контекст нужно сохранять и восстанавливать назад, иначе при попытке использовать такой Canvas из-за блокировки будет Canvas don't allow drawing"
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977099
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

1. Нет, багрерорты не делает. Хватает подробных логов.

2. Из-за этого может возникнуть проблема (ну я так вижу), только если перекрыть WM_PAINT, вызвать inherited и потом что-то пытаться рисовать через канвас. Ну это как бы обычно сразу не работает, если еще и логику с ветвлениями не наворотить...

В общем, у меня с этим проблем не было.

Ну, и главное - я не понял, при чем здесь Post/SendMessage.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977115
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

1. стоит добавить. много интересного приходит чего никогда не наблюдаешь и повторить не получается, но после фикса багрепорты исчезают
2. нет, схема простая, у тебя идёт рисование, дальше "случайно" срабатывает обработчик сообщения, в котором тоже по различным причинам срабатывает эта же прорисовка - вот тебе неявная рекурсия, дальше обработчик возвращается в прорисовку и получаешь фейл, т.к. Canvas.Handle = 0.
А так как багрепорты у тебя не настроены, стандартный обработчик покажет пользователю окно с ошибкой, а он его благополучно закроет и забудет.

но если софт пишется для 10-ка человек, то конечно можно и дальше не заморачиваться на мелочи, типа 1 раз за млн запусков
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977150
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
схема простая, у тебя идёт рисование, дальше "случайно" срабатывает обработчик сообщения, в котором тоже по различным причинам срабатывает эта же прорисовка - вот тебе неявная рекурсия
"Случайно" - это либо вызов UpdateWindow из WM_PAINT, либо принудительная выкрутка сообщений с обработкой (типа Application.ProcessMessages) из WM_PAINT?
Тут даже обсуждать нечего.
Всё так же не понятно, при чем здесь Post/SendMessage (ну кроме SendMessage (из WM_PAINT!!!), у которого в обработчике UpdateWindow или выкрутка )

kealon(Ruslan)
А так как багрепорты у тебя не настроены, стандартный обработчик покажет пользователю окно с ошибкой, а он его благополучно закроет и забудет.
И в мои логи попадёт всё, вплоть до того, какую кнопку нажал пользователь, а если это исключение - добавится еще и лог, который алерт вызовет и техподдержка будет разбирать все логи.

kealon(Ruslan)
софт пишется для 10-ка человек

Нет, еще три нуля - порядок где-то таков.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977242
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

плохо копаешь, копай WM_PRINT где юзается
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977248
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
YuRock,

плохо копаешь, копай WM_PRINT где юзается
Возможно.
В сфере моих программ такие сообщения не приходят.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977293
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Возможно.
В сфере моих программ такие сообщения не приходят.
ну вот добавишь стили, или компонент какой с прозрачностью и пойдёт коса по камням
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977547
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
YuRock
Возможно.
В сфере моих программ такие сообщения не приходят.
ну вот добавишь стили, или компонент какой с прозрачностью и пойдёт коса по камням
Да нет, не добавлю.
Я вообще не использую VCL давно, свою библиотеку использую. Но и сейчас, и раньше, когда использовал - не было проблем с отправкой и обработкой сообщений (видимо, компоненты, стреляющие мне в ногу, не попадались).
Чего не могу сказать про Synchronize - в библиотеках-драйверах для СУБД эта гадость нет-нет, да используется, бывает, ну и доставляет тогда проблем, которые обходить приходится костылями, или переписывать их код на Send/PostMessage.
...
Рейтинг: 0 / 0
В каких случаях вы используете метод TThread.Queue?
    #39977587
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Да нет, не добавлю.
Я вообще не использую VCL давно, свою библиотеку использую. Но и сейчас, и раньше, когда использовал - не было проблем с отправкой и обработкой сообщений (видимо, компоненты, стреляющие мне в ногу, не попадались).
Чего не могу сказать про Synchronize - в библиотеках-драйверах для СУБД эта гадость нет-нет, да используется, бывает, ну и доставляет тогда проблем, которые обходить приходится костылями, или переписывать их код на Send/PostMessage.
нет VCL - нет и проблем с ней
так то и у меня есть, но приходится жить с тем за что денюжку платят - потому разговор про то как с ней жить:-)

PS: те кто используют Synchronize и не дают чем её имплементировать, молодцы конеш - тоже таких встречал
...
Рейтинг: 0 / 0
21 сообщений из 46, страница 2 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / В каких случаях вы используете метод TThread.Queue?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]