Create Responsive Apps by Running Calculations in the Background
This topic shows how to make an app more responsive by using the background pool. Usually, MATLAB® suspends execution while running calculations. While MATLAB is suspended, you are unable to interrupt the app. To make your apps more responsive, use the background pool to run calculations in the background. When MATLAB runs calculations in the background, your app can immediately respond to user interface interactions.
If you want to modify an existing app that runs code in the background, see Responsive App That Calculates and Plots Simple Curves.
In this topic, you:
Open an existing app that does not run any code in the background.
Modify a function to allow the app to run code in the background.
Write a function to automatically update a plot after code finishes running in the background.
Modify existing callbacks to allow your app to immediately respond to user interface interactions and interrupt calculations.
Open App Designer App
The app you use in this example allows you to select a function, then calculate and plot
y
-axis data depending on built-in x
-axis
data.
Run this command to open a working copy of the PlotCurve
app.
openExample('matlab/PlotCurveAppExample')
Use this app as a starting point as you modify and reorganize the app code. The app has five functions:
getFunction
— Use the value from the drop-downfcnDropDown
to select a functionfcn
. The custom functions available as supporting files usepause(rand)
to simulate a nontrivial calculation.createData
— UsegetFunction
to get a functionfcn
, then use that function to computey = fcn(x)
in iterations of afor
-loop. Thefor
-loop suspends MATLAB execution until it is finished.updatePlot
— Update the plot represented byapp.UIAxes
with eachy
-axis data point after it is calculated.clearPlot
— Clear the plot.toggleButtons
— Switch between enabling the Start button or Stop button.
Edit code by selecting Code View in the App Designer window.
Add a Future
Array to the Properties
When you run a function in the background, you create a Future
object.
You can fetch outputs from the Future
object using fetchOutputs
.
To make your app responsive, you need to store all of the Future
objects the app creates. Then, you can use cancel
to stop
the calculations running in the background when the user of the app clicks the
Stop button or uses the drop down
fcnDropDown
.
To store the Future
objects the app creates, you must add a private
property to your app. In the App Designer toolstrip, click Property > Private Property, then name the property
F
.
properties (Access = private) h % Line object X % x-axis data F % Futures for calculation end
Create y
-axis Data in the Background
The createData
function creates the y
-axis data
when the user of the app clicks the Start button. Edit the function
to calculate the y
-axis data in the background.
Use
parfeval
(Parallel Computing Toolbox) andbackgroundPool
to run the functionfcn
in the background. In each iteration of thefor
-loop, store eachFuture
in an arrayf
.Store the future array as the
F
property of the app.Use
afterEach
to run a functiononFutureDone
that updates a plot after each element ofapp.F
completes. SpecifyPassFuture
astrue
to run the function using eachFuture
element.Use
afterAll
to toggle between the Start and Stop buttons after MATLAB finishes calculating all of they
-axis data.
function createData(app) % Create data for the x-axis and y-axis. % Update a plot while the data is being created. % Get function fcn = app.getFunction; % x-axis data app.X = 5 * 1:100; % y-axis data for i = 1:numel(app.X) % Run fcn(x) in the background f(i) = parfeval(backgroundPool,fcn,1,app.X(i)); end % Store the Future array app.F = f; % Update the plot after each Future finishes afterEach(app.F,@app.onFutureDone,0,PassFuture=true); % Toggle the buttons after all Future objects finish afterAll(app.F,@(~)app.toggleButtons,0); end
Automatically Update Plot After Data Is Calculated in the Background
Create a new function to automatically update the plot after each
Future
finishes.
In the App Designer toolstrip, click Function > Private Function, then name the function
onFutureDone
.If the
Future
object finished with an error, immediately return from the function.If the
Future
object did not finish with an error, use theID
property off
to find the index of the elementf
in the arrayapp.F
. The index of theFuture
objectf
must match the index of thex
-axis data point.Update the plot with the result from
f
and the matchingx
-axis data point by, using the indexidx
.
function onFutureDone(app,f) % Do not update the plot if there was an error if ~isempty(f.Error) return end % Find the index of this future idx = ([app.F.ID] == f.ID); % Update the plot using the result app.updatePlot(fetchOutputs(f),idx); end
Make Your App More Responsive by Canceling the Future
Array
To make your app more responsive, edit callbacks cancel the Future
array app.F
after you:
Change the value using the drop-down
fcnDropDown
.function fcnDropDownValueChanged(app, event) % Stop futures if ~isempty(app.F) cancel(app.F) end app.clearPlot if app.StartButton.Enable == false app.createData end end
Push the Stop button.
function StopButtonPushed(app, event) % Stop futures if ~isempty(app.F) cancel(app.F) end app.toggleButtons end
Request the app to close.
function UIFigureCloseRequest(app, event) % Stop futures if ~isempty(app.F) cancel(app.F) end delete(app) end
Responsive App That Calculates and Plots Simple Curves
This example shows an app that calculates and plots simple curves. You can select a function to plot, then plot that function. The app uses a for
-loop to calculate the y
-axis data in the background. MATLAB does not suspend execution while calculating the data, and therefore you are able to stop the app or update the type of plot while the data is being calculated.
Run the PlotCurveBackground
app by clicking the Run button in App Designer.
See Also
parfeval
| backgroundPool
| appdesigner