DisplayName
DisplayName

Reputation: 249

How to implement async waiting loop with packaged_task in C++?

Let us say, that we use packaged_task for implementing async work in a program.

#include <map>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <iterator>
#include <future>
#include <thread>
#include <chrono>

int main()
{
    std::packaged_task<int()> packagedTaskOne([]()
        {
            using namespace std::chrono_literals;
            std::this_thread::sleep_for(4s);
            return 4;
        });

    std::future<int> futureResultOne = packagedTaskOne.get_future();
    std::thread tOne(std::move(packagedTaskOne));

    futureResultOne.wait();
    tOne.join();

    std::cout << "done\n";

    return 0;
}

I can barely imagine how to implement waiting cursor in C#, because I can use something like while(!Task.Run(async () => await _service.GetValue()).IsCompleted) and output some dots that show loading. I want the same with packaged_task but I do not understand how to fuse it with while loop because I do not get what a condition I should for checking is this thread completed. How to make the same loop in C++ with packaged_task?

Upvotes: 0

Views: 243

Answers (1)

asmmo
asmmo

Reputation: 7100

If you don't want to use futureResultOne.get(); to avoid blocking, the following is a way to check if your task has finished or not in the main (you can use an independent one of course) thread.

#include <iostream>
#include <future>
#include <thread>
#include <chrono>
#include <condition_variable>

using namespace std::chrono_literals;

std::condition_variable cv;
bool theThreadHasFinished;
std::mutex mut;
int main()
{
    std::packaged_task<int()> packagedTaskOne([]{
                                                  std::this_thread::sleep_for(4s);
                                                  return 4;
                                              });

    std::future<int> futureResultOne = packagedTaskOne.get_future();
    std::thread tOne([&]{packagedTaskOne();
        std::lock_guard lg{mut};
        theThreadHasFinished = true;
        cv.notify_all();});
    tOne.detach();
    std::unique_lock<std::mutex> lock{ mut };
    cv.wait(lock, [ ](){ return theThreadHasFinished; });
    std::cout << "done\n";

    return 0;
}

You can use a while loop ad wait_for but this consumes your resources

Upvotes: 1

Related Questions