LINUX.ORG.RU

Коллбеки vs синхронный код

 ,


1

2

(Речь идёт о Qt4 и C++03.)

Такая ситуация. По нажатию кнопки необходимо выполнить запрос через сеть. Если всё окей, то надо взять полученные от сервера данные и выполнить действие A. Если запрос облажался, то надо показать пользователю сообщение об ошибке и выполнить действие Б. Запросы к сети выполняются сторонним объектом Г, у которого исключительно синхронный блокирующий интерфейс.

Очевидно, что дёргать Г на главном потоке нельзя, так как это заблокирует event loop. Поэтому Г-запросы выполняются в побочном потоке через QRunnable-обёрточку, которая сохраняет результаты и сигналит о их завершении (или факапе).

Есть как минимум два подхода к подобной обработке: асинхронный через коллбек-слоты, которые связываются с сигналами обёрточки и просто вызываются, когда приходит время; и синхронный через QEventLoop, когда сигналы обёрточки связываются с QEventLoop::quit() и пока там Г думает, обработчик нажатия на кнопку крутит локальный event loop.

Какой способ предпочитает использовать лоровец? Есть ли какие-либо технические преимущества у какого-либо из них?

★★★

и синхронный через QEventLoop, когда сигналы обёрточки связываются с QEventLoop::quit() и пока там Г думает, обработчик нажатия на кнопку крутит локальный event loop.

Я не понял, что ты здесь курнул, но вроде бы все делают по способу один.

UVV ★★★★★
()

Два месяца пытался понять причину бага в коде с вложенными event loop. Наверное, всё же не стоит лезть глубже, если сигналов достаточно.

i-rinat ★★★★★
()

Коллбек ставит запрос в одну из очередей запросов, которые разгребаются в event loop.

tailgunner ★★★★★
()

Первый способ истинно правильный и верный. Второй мог придумать только анонимус наркоман.

nanoolinux ★★★★
()

асинхронный через коллбек-слоты, которые связываются с сигналами обёрточки и просто вызываются, когда приходит время

Канонично.

и синхронный через QEventLoop, когда сигналы обёрточки связываются с QEventLoop::quit() и пока там Г думает, обработчик нажатия на кнопку крутит локальный event loop.

Виндус 98 стайл.

yoghurt ★★★★★
()
Ответ на: комментарий от nanoolinux

Второй мог придумать только анонимус наркоман.

В суровые 90е-нулевые был весьма себе распространенный паттерн в среде Win32-API разрабов, о нём даже в книжках писали.

yoghurt ★★★★★
()

первый вариант конечно... А вообще, если у тебя объект Г крутиться не в qt потоке, а, например в нативном pthread, то 1-й вариант не подойдет, надо делать в нативном потоке post_event, а в главном потоке переопределять event и обрабатывать только свои события

energyclab
()

когда сигналы обёрточки связываются с QEventLoop::quit() и пока там Г думает, обработчик нажатия на кнопку крутит локальный event loop. Есть ли какие-либо технические преимущества у какого-либо из них?

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

terminator-101
()

В большинстве случаев лучше асинхронный. Синхронный может пригодиться только если тебе надо сделать цепочку вызовов к серверу, где каждый последующий вызов зависит от данных из предыдущих вызовов и таких вызовов много - тогда код с синхронным вызовом будет смотреться аккуратнее -> меньше ошибок.

ncuxer
()

Когда надо что-то тормозное отдельно от GUI, а сую это в тред... Я так делаю:

QThread thread;
MyClass my; // от QObject
my.moveToThread(&thread);
... // connect signals
thread.start();
А если надо вызвать слотик в объекте - то QMetaObject::invokeMethod. А коннекты сигналов со слотами с типом queued.

Если это не правильно, поправьте меня. Просто как мне кажется это именно то что хотел ТС. У меня такое решение...

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.