外部プロセスを非同期で起動する

バックグラウンドでプロセスを実行し、プロセス終了と同時に、その終了コードに応じてアクションを実行しなければならないことがあります。4D v19 R4 より、新しい 4D.SystemWorker クラスを使ってバックグラウンドでプロセスを開始し、プロセスが情報を返したときに自動的にコールバックメソッドを実行できるようになりました。この方法では、外部プロセスが実行中でもアプリケーションの UI は応答し続け、終了したらすぐにユーザーに結果を表示することができます!

HDI: システムワーカー

SystemWorker は、コンストラクター 4D.SystemWorker.new(process) によって作成されるオブジェクトです。引数として渡されたプロセスを開始し、同プロセスの終了まで待機する新しいワーカーを作成します。

ここでは、SystemWorker を使ってさまざまな git コマンドを実行する例をいくつか紹介します。

まずはシンプルに、マシンにインストールされている git のバージョンを取得してみましょう。これには 2つの方法があります。

  • 非同期でおこない、クライアントが引き続きインターフェースを自由に使えるようにしたい場合は、プロセス終了時に呼び出されるコールバックを使用します:
$param:=New object
// プロセスがすでに終了していなければ 2秒後にプロセスを閉じます
$param.timeout:=2
// システムワーカーがレスポンスを受領した時に呼び出されるコールバックフォーミュラ
$param.onResponse:=Formula(ALERT($1.response))
// 上に指定した引数でシステムワーカーを起動します
$sys:=4D.SystemWorker.new("git --version"; $param)
  • プロセスの応答を待ちたい場合は、.wait() を使います:
$param:=New object
// プロセスがすでに終了していなければ 2秒後にプロセスを閉じます
$param.timeout:=2
// 上に指定した引数でシステムワーカーを起動します
$sys:=4D.SystemWorker.new("git --version";$param)

// プロセス終了まで待機し、Git のレスポンスを返します
ALERT($sys.wait().response)

続けて、コミットメッセージを待機するコミットをしてみましょう。この例では、プロセスは標準的な入力を待ちます。コンソールであれば、コンソールがユーザーの値入力を待つということです:

このような場合には、.postMessage() 関数を使用してメッセージを送信し、.closeInput() 関数を使用してメッセージが送信されたことをプロセスに指示することができます:

$param:=New object
$param.currentDirectory:=$myProjectDirectory

$sys:=4D.SystemWorker.new("git commit -F -";$param)
$sys.postMessage("This is my first commit")
$sys.closeInput()

お気づきのように、システムワーカーは Launch external process コマンドを超えるものです。非同期でプロセスを起動し、呼び出されたプロセスから outputStream と errorStream を簡単に受け取ることができます。さらに、プロセスと通信する新しい方法として .postMessage() 関数を使うことができます。

この機能を上の HDI でテストし、複数のプロセスを並行して起動させる方法を試してみてください。

詳しくはデベロッパーセンターをご覧ください。

Fabrice Mainguené
- Product Owner -Fabrice Mainguenéは、2016年11月に4D Programチームに参加しました。プロダクトオーナーとして、彼はユーザーストーリーを書き、それを機能仕様に変換する役割を担っています。CNAMでコンピュータサイエンスの学士号を取得した後、FabriceはWindev開発者として小さなソフトウェア出版社に入社しました。その後、彼は産業および貿易分野のさまざまな企業で、Windev および Web 開発者として、また新機能の技術アドバイザーとして働きました。