バックグラウンドでの計算の実行による応答性に優れたアプリの作成
このトピックでは、バックグラウンド プールを使用してアプリの応答性を高める方法を示します。通常、計算の実行中は MATLAB® が実行を一時停止します。MATLAB が一時停止している間はアプリを中断できません。アプリの応答性を高めるには、バックグラウンド プールを使用してバックグラウンドで計算を実行します。MATLAB による計算をバックグラウンドで実行すると、アプリはユーザー インターフェイスの操作に即座に応答できます。
コードをバックグラウンドで実行する既存のアプリを変更する場合は、簡単な曲線を計算してプロットする応答性に優れたアプリを参照してください。
このトピックでは以下を行います。
コードをバックグラウンドで実行しない既存のアプリを開きます。
アプリがコードをバックグラウンドで実行できるように関数を変更します。
バックグラウンドでのコードの実行が完了した後にプロットを自動的に更新する関数を記述します。
アプリがユーザー インターフェイスの操作に即座に応答して計算を中断できるように既存のコールバックを変更します。
App Designer アプリを開く
この例で使用するアプリでは、関数を選択し、組み込みの x 軸のデータに応じて y 軸のデータを計算してプロットできます。
次のコマンドを実行して PlotCurve アプリの作業コピーを開きます。
openExample('matlab/PlotCurveAppExample')このアプリをアプリ コードを変更して再編成する開始点として使用します。アプリには 5 つの関数があります。
getFunction— ドロップダウンfcnDropDownの値を使用して関数fcnを選択します。サポート ファイルとして使用できるカスタム関数で、重要な計算をpause(rand)を使用してシミュレートします。createData—getFunctionを使用して関数fcnを取得し、その関数をforループの反復で使用してy = fcn(x)を計算します。forループが完了するまで MATLAB の実行が一時停止します。updatePlot—app.UIAxesで表されるプロットのy軸の各データ点を計算後に更新します。clearPlot— プロットをクリアします。toggleButtons— [Start] ボタンと [Stop] ボタンのどちらを有効にするかを切り替えます。
App Designer ウィンドウで [コード ビュー] を選択してコードを編集します。
プロパティに Future 配列を追加
関数をバックグラウンドで実行するときは、Future オブジェクトを作成します。Future オブジェクトからの出力は fetchOutputs を使用して取得できます。
アプリの応答性を高めるには、アプリで作成されるすべての Future オブジェクトを格納する必要があります。これにより、アプリのユーザーが [Stop] ボタンをクリックするかドロップダウン fcnDropDown を使用したときに、バックグラウンドで実行中の計算を cancel を使用して停止できるようになります。
アプリで作成される Future オブジェクトを格納するには、アプリにプライベート プロパティを追加する必要があります。App Designer のツールストリップで [プロパティ] 、 [プライベート プロパティ] をクリックし、プロパティに F という名前を付けます。
properties (Access = private) h % Line object X % x-axis data F % Futures for calculation end
y 軸のデータをバックグラウンドで作成
アプリのユーザーが [Start] ボタンをクリックすると、関数 createData で y 軸のデータが作成されます。y 軸のデータをバックグラウンドで計算するように関数を編集します。
parfevalとbackgroundPoolを使用して関数fcnをバックグラウンドで実行します。forループの各反復で、各Futureを配列fに格納します。future 配列をアプリの
Fプロパティとして格納します。afterEachを使用して、app.Fの各要素が完了するたびにプロットを更新する関数onFutureDoneを実行します。Futureの各要素を使用して関数を実行するように、PassFutureをtrueと指定します。y軸のすべてのデータの計算を MATLAB が完了した後に、afterAllを使用して [Start] ボタンと [Stop] ボタンを切り替えます。
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
バックグラウンドでのデータの計算の完了後に自動的にプロットを更新
各 Future の完了後にプロットを自動的に更新する新しい関数を作成します。
App Designer のツールストリップで [関数] 、 [プライベート関数] をクリックし、関数に
onFutureDoneという名前を付けます。Futureオブジェクトがエラーで終了したら、関数からすぐに戻ります。Futureオブジェクトがエラーで終了しなければ、fのIDプロパティを使用して配列app.Fにおける要素fのインデックスを調べます。Futureオブジェクトfのインデックスはx軸のデータ点のインデックスと一致しなければなりません。fの結果と対応するx軸のデータ点 (インデックス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
Future 配列をキャンセルしてアプリの応答性を向上
アプリの応答性を高めるために、以下の実行後に Future 配列 app.F をキャンセルするようにコールバックを編集します。
ドロップダウン
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
[Stop] ボタンを押す。
function StopButtonPushed(app, event) % Stop futures if ~isempty(app.F) cancel(app.F) end app.toggleButtons end
アプリを閉じるように要求する。
function UIFigureCloseRequest(app, event) % Stop futures if ~isempty(app.F) cancel(app.F) end delete(app) end
簡単な曲線を計算してプロットする応答性に優れたアプリ
この例では、簡単な曲線を計算してプロットするアプリを示します。プロットする関数を選択し、その関数をプロットできます。このアプリでは、for ループを使用してバックグラウンドで y 軸のデータを計算します。MATLAB はデータの計算中に実行を一時停止しないため、データの計算中にアプリを停止したりプロットのタイプを更新したりできます。
App Designer で [実行] ボタンをクリックして PlotCurveBackground アプリを実行します。

参考
parfeval | backgroundPool | appdesigner