w1th0utnam3
w1th0utnam3

Reputation: 1012

Most elegant way of callback from method launched with async

What is the most elegant way to implement a non-static callback when starting a function with async?

Problem: I want a ui to show data after a computation finished without blocking the ui. Please don't consider using some ui event-loops that may be present in ui libraries because I'm looking for a more general and elegant solution using pure C++ (11).

I have a MainWindow class that handles the user interface and a Simulation class that makes some complex calculations in a non-static run(SimulationSettings settings) method. Part of the settings structure passed with the run-method is a pointer to a DataManager-object that stores input and output for the simulation. The DataManager as well as the Simulation are created as members of the MainWindow. I start the simulation with the following lines in a non-static method of the MainWindow class:

auto run_simulation = std::bind(&Simulation::run, m_simulation, settings);
std::async(run_simulation);

After the run(...) method returns I want my MainWindow to execute its method processesResults() that does some postprocessing with the data which is now saved in the DataManager - but of course without blocking the rest of the MainWindow functionality during the simulation. Is there a way to do this "callback" without giving the Simulation a pointer to the MainWindow object? Is it possible with a function pointer? Or is my whole concept of doing asynchronous work bad? I'm pretty new to threads etc. and in my opinion it is a bit hard to find good writing about this C++11 area with the thread, future, promise ... classes.

Upvotes: 0

Views: 1722

Answers (2)

let
let

Reputation: 46

If you just want to do something after the simulation finishes you can use the following lambda expression:

auto run_simulation = [this, &settings]() {
    m_simulation.run(settings);
    processResults();
};
std::async(run_simulation);

Upvotes: 2

Jarod42
Jarod42

Reputation: 217293

You may use future::wait_for to know when the simulation finished

auto fut = std::async(run_similation);

while (true) {
    // Your main loop

    std::chrono::milliseconds span (1);
    if (fut.valid() && fut.wait_for(span) != std::future_status::timeout) {
        // simulation is finished
    }
}

Upvotes: 0

Related Questions