Ломатся выгрузка - асинхронные запросы

EclipsedFlow

Известный
Автор темы
Проверенный
1,047
476
Много лет и сил потрачено, а нормального результата я так и не получил. Вкратце, хочу сделать асинхронные запросы чтобы основной поток не блокировался. Код ниже работает, но ломает выгрузку (скорее всего из-за не нормальную выгрузку std::future) но не требует для этого отдельного потока. Как починить выгрузку плагина или посоветуйте, поделитесь кодом как лучше сделать асинхронные запросы.


C++:
class CRequest {
private:
    struct stRequestAdd {
        cpr::AsyncResponse m_Response;
        std::function<void(const std::string, const cpr::Response)> m_Callback;
    };
    std::map<std::string, stRequestAdd> m_RequestPool;
public:
    void Handler(void)
    {
        for (auto&& req : m_RequestPool)
        {
            if (req.second.m_Response.valid() && req.second.m_Response.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
            {
                auto& key = req.first;
                auto& response = req.second.m_Response.get();
                req.second.m_Callback(key, response);
                m_RequestPool.erase(key);
            }
        }
    }
    void Get(const std::string key, const std::string url, std::function<void(const std::string, const cpr::Response)> callback)
    {
        stRequestAdd tmp;
        tmp.m_Response = cpr::GetAsync(cpr::Url{ url });
        tmp.m_Callback = callback;
        m_RequestPool.emplace(std::make_pair(key, std::move(tmp)));
    }
};
 

RedHolms

Известный
Проверенный
620
367
Много лет и сил потрачено, а нормального результата я так и не получил. Вкратце, хочу сделать асинхронные запросы чтобы основной поток не блокировался. Код ниже работает, но ломает выгрузку (скорее всего из-за не нормальную выгрузку std::future) но не требует для этого отдельного потока. Как починить выгрузку плагина или посоветуйте, поделитесь кодом как лучше сделать асинхронные запросы.


C++:
class CRequest {
private:
    struct stRequestAdd {
        cpr::AsyncResponse m_Response;
        std::function<void(const std::string, const cpr::Response)> m_Callback;
    };
    std::map<std::string, stRequestAdd> m_RequestPool;
public:
    void Handler(void)
    {
        for (auto&& req : m_RequestPool)
        {
            if (req.second.m_Response.valid() && req.second.m_Response.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
            {
                auto& key = req.first;
                auto& response = req.second.m_Response.get();
                req.second.m_Callback(key, response);
                m_RequestPool.erase(key);
            }
        }
    }
    void Get(const std::string key, const std::string url, std::function<void(const std::string, const cpr::Response)> callback)
    {
        stRequestAdd tmp;
        tmp.m_Response = cpr::GetAsync(cpr::Url{ url });
        tmp.m_Callback = callback;
        m_RequestPool.emplace(std::make_pair(key, std::move(tmp)));
    }
};
Как вариант вообще использовать неблокирующие сокеты, но это уже зависит от того, какую библиотеку ты используешь для запросов

Как вариант, вручную создавать потоки, и где-то их сохранять, и если вызван DllMain с кодом завершения, завершать все потоки, либо join'ить их