Появилось проблема в оптимизации приложения которая работает с БД(MySQL). Есть весьма большой SQL запрос(выборка с множеством inner join) который выполняется в конструкторе и на основе него строится UI. И ПО висит во время запроса, а это плохое поведение пользователи сейчас нервные приложение могут и закрыть... Я бы хотел перенести работу с БД в отдельный поток но к сожалению я не имел опыта в этом.
Можно ли минимально работающий пример работы много поточного приложения где один поток рисует UI и занимается бизнес логикой а другой работой с БД. А я бы оттолкнулся от этого примера и переписал бы свой. Спасибо за внимание.
Пример подобного кода можете посмотреть в моем гите: класс инкапсулирующий QSqlDatabase и предоставляющий шаблонные методы для вызова в другом потоке: тыц. Пример использования можете найти тут: тыц. Если вкратце, то нижеприведенная связка методов:
template <typename DB, typename Function , typename ...Args, typename CallBack, typename ReturnValue, typename ConnSetter>
QUuid Database::callAsync(DB* db, ConnSetter&& setter, QFutureWatcher<ReturnValue>* watcher, Function&& query, CallBack&& callBack, Args&& ...args)
{
auto id = prepareToAsyncCall(watcher, std::forward<CallBack>(callBack));
QFuture<ReturnValue> futureValue
= QtConcurrent::run(
bind(
exceptionWrapper <DB, ReturnValue, Function, ConnSetter, Args...>, id, watcher, db, forward<Function>(query), setter, forward<Args>(args)...));
watcher->setFuture(futureValue);
return id;
}
template <typename DB ,typename ReturnValue, typename Function ,typename ConnSetter, typename ...Args>
auto Database::exceptionWrapper (QUuid id, QFutureWatcher<ReturnValue>* w, DB* db, Function function, ConnSetter setter, Args& ...args)
-> decltype((db->*function)(args...))
{
try
{
QScopedPointer <DB> tempDbConn(new DB(id));
setter(tempDbConn.data());
QObject::connect(tempDbConn.data(), &Database::queryCanceled, tempDbConn.data(),
[w](){w->disconnect(); w->cancel();}, Qt::DirectConnection);
db->setConnectionOptions(tempDbConn.data());
return (tempDbConn.data()->*function)(args...);
}
catch (std::exception& e)
{
throw ThreadDbException(e);
}
}
Позволяет вызвать любой метод класса Database
в потоке, получить результат через QFuture и если что вернуть в главный поток исключение.
Если возникнут какие-либо вопросы, то можете написать мне на почту (она указана в профиле).
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как можно модифицировать ПО для мультипоточной работы
столкнулся с одной проблемой, и не могу понять, почему так происходит
Подскажите, можно ли реализовать следующую задумку: