Reputation: 1012
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
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
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