Диалог запуска в главном потоке, ожидающий результата рабочего потока - PullRequest
0 голосов
/ 20 марта 2020

У меня есть приложение, которое отправляет HTTP-запросы и обрабатывает полученный ответ. Основной поток блокируется до тех пор, пока ответ не вернется, иначе мы не смогли обработать данные. Чтобы отправить эти запросы, пользователь должен пройти аутентификацию. Я sh поймаю ответ 401 и, прежде чем вернуть ответ для обработки моим приложением, запросит у пользователя аутентификацию. В зависимости от успеха я хочу повторить попытку отправки исходного запроса и вернуть этот ответ вместо этого, или, если аутентификация не удалась, вернуть исходный ответ 401.

Я использую C ++ REST SDK для отправки HTTP-запросов. Это происходит в другом потоке (pplx :: task). Я также использую модальное диалоговое окно MF C для запроса аутентификации. Некоторые из вас могут увидеть тупик, который возникает. Если нет, позвольте мне объяснить подробнее.

Основной поток ожидает завершения HTTP-запроса. Внутри этой темы я ловлю 401 и wi sh, чтобы запустить диалог. Для этого я использую boost::signal. Этот сигнал вызывает SendMessage к дескриптору I sh, чтобы отобразить диалоговое окно. После того, как сообщение обработано сообщением MF C l oop, оно запустит диалоговое окно (в главном потоке). Это зависит от сообщения MF C l oop, которое блокируется в ожидании HTTP-запроса. Короче говоря, основной поток уже ожидает окончания запроса sh, поэтому он не может запустить свое сообщение l oop для получения вызова от SendMessage.

Основной поток ожидает работника нить. Рабочий поток должен запустить диалог в главном потоке, прежде чем он сможет продолжить. Тупик. У кого-нибудь есть какие-нибудь умные решения для обхода этого?

1 Ответ

0 голосов
/ 20 марта 2020

Я думаю, что самое простое решение здесь - изменить способ обработки ваших тем.

Я предлагаю, чтобы вместо одного потока для запросов вы создавали новый поток для каждого запроса, а затем возвращали ему код состояния (независимо от того, что это), вы можете обрабатывать любые логи c для повторной попытки аутентификации в вашем основном потоке (т. е. отобразить диалоговое окно аутентификации, а затем повторно запустить поток аутентификации с учетными данными).

Это также позволяет лучше инкапсулировать ваш обработчик запросов, что является большим плюсом. Чтобы правильно инкапсулировать эту логику c (чтобы вам не приходилось проверять каждый запрос), вы должны определить какой-то тип обработчика запроса (либо класс, либо функцию). Например,

StatusCode make_reqeust(...) {
  // Deal with the logic on authentication here
}

Где StatusCode - это тип для кода состояния HTTP.

Конечно, это не решает проблему вашего потока пользовательского интерфейса, потенциально ожидающего завершения рабочего потока sh , так что вам также нужен некоторый метод refre sh пользовательского интерфейса, который вызывается каждые x раз и который проверяет состояние всех рабочих потоков (т. е. проверяя возвращенные std::future). Вы также хотели бы изменить приведенный выше пример, чтобы он мог порождать отдельный поток и возвращать std::future в этом случае.

...