Main Content

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-down fcnDropDown to select a function fcn. The custom functions available as supporting files use pause(rand) to simulate a nontrivial calculation.

  • createData — Use getFunction to get a function fcn, then use that function to compute y = fcn(x) in iterations of a for-loop. The for-loop suspends MATLAB execution until it is finished.

  • updatePlot — Update the plot represented by app.UIAxes with each y-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.

  1. Use parfeval (Parallel Computing Toolbox) and backgroundPool to run the function fcn in the background. In each iteration of the for-loop, store each Future in an array f.

  2. Store the future array as the F property of the app.

  3. Use afterEach to run a function onFutureDone that updates a plot after each element of app.F completes. Specify PassFuture as true to run the function using each Future element.

  4. Use afterAll to toggle between the Start and Stop buttons after MATLAB finishes calculating all of the y-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.

  1. In the App Designer toolstrip, click Function > Private Function, then name the function onFutureDone.

  2. If the Future object finished with an error, immediately return from the function.

  3. If the Future object did not finish with an error, use the ID property of f to find the index of the element f in the array app.F. The index of the Future object f must match the index of the x-axis data point.

  4. Update the plot with the result from f and the matching x-axis data point by, using the index idx.

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

| |

Related Topics