広告
公式ドキュメントの和訳です。
概要
Introduction
マルチ・スレッド・アプリケーションを使用したいという願望は、極めて人気が高くなりました。コンピュータ・プロセッサが、複数のコアを持つようになったとき、マルチスレッドは、コンピュータの全処理能力をより有効に活用するための1つの方法です。概念では、素晴らしい考えですが、実際には、実世界の作業工程に必ずしも適合しません。そして、実装するのが極めて困難です。ユーザー・インターフェイスを備えた、ほとんどのアプリケーションのように、Fusionのほとんどは、シングル・スレッドです。モデルを構築する各々の手順は、前の手順の結果に依存しています。例えば、あなたが、計算するために数秒かかる、極めて複雑なフィーチャを作成する場合、あなたが、次のフィーチャを定義し始める前に、モデルを、完成する必要があるため、それが、まだフィーチャを計算している間、モデリングを続けるために、あなたにコントロールを戻すことは、Fusionのために、意味がありません。理想的には、その工程の一部を高速化するために、機能の計算には、マルチスレッドが使用されますが、それは、また、実装するのが困難です。
あなたが、コンピュータで処理されるスレッドを一連の命令とみなす場合、マルチスレッドは、多くのスレッドを同時に処理できます。複雑なタスクの処理の高速化するために用いられている一方で、また、あなたが、発生するバックグラウンド処理を必要とする場合、複数のスレッドは対話型アプリケーションに極めて役立ちます。しかし、まだ、ユーザーは、アプリケーションと対話したいと考えます。それは、あなたが、以下の例を後で見る、Fusion APIで、提供する大きな利点です。
覚えておくことが、重要です。ほとんどのFusionは、一つのメイン・スレッドで実行され、そして、これには、ユーザー・インターフェイスとあなたのプログラムが、含まれています。あなたは、それを誰もが、それらの順番を待つ必要がある単一のキューと考えることができます。そして、1人だけは、一度に、待たれています。あなたのプログラムが、関数を実行しているとき、Fusionの中で、何も起こっていません。これが、どのようにアドインとコマンドで動作するかを見てみましょう。アドインが読み込まれるとき、Fusionは、その実行された関数を呼び出します。そこで、あなたのアドインは、メイン・スレッドで活発に実行されています。そして、Fusionでは、何も起こっていません。一旦、run関数が完了すると、あなたのアドインが、バックグラウンドに位置している間、Fusionは、他のキューの動作を処理し始めます。ユーザーが、アドインが定義したコマンドを実行するとき、commandCreatedイベントは、アドインに対して、発生します。これは、アドインをキューの前方へ移動します。そして、作成されたイベントのコマンドのためのそのイベント・ハンドラが、実行されている間、それは、メイン・スレッドを持っています。コマンドの作成されたイベント・ハンドラでは、コマンド・ダイアログを定義し、そして、他のイベントに接続します。一旦、コマンドの作成されたイベントが、完了すると、メイン・スレッドのコントロールをあきらめます。そして、Fusionが引き継ぎ、ユーザーは、コマンド・ダイアログと対話できます。ユーザーが、ダイアログと対話するとき、Fusionは、続いて、何が生じているか知らせるイベントを、アドインに発生しますが、また、これは、イベントに応答して、アドインが、メイン・スレッドで実行できます。イベントを使用して、Fusionと他のアドインは、メイン・スレッドを共有することができます。
それは、アドインを実行し続け、そして、メイン・スレッドをあきらめたくないとき、問題になります。これは、Fusionが、他の作業を行うことから、妨げます。例えば、アドインが、既知のファイルを監視したい場合、修正された日付が、変更した場合、これを行う1つの方法は、ファイルの日付を継続的に確認するループを行うことです。しかしながら、あなたが、アドインで関数を持っている場合、メイン・スレッドを独占しているため、これを行いFusionの利用を妨げます。Fusionは、一時的に、キューが動作を処理できるFusionに、コントロールを戻すdoEvents関数をサポートします。そして、その次に、それは、実行している関数に戻ります。これを長期的なループで使用することは、適切ではありません。そして、ある時点で、Fusionがクラッシュする可能性があります。より素晴らしい解決策は、アドインに、実行され、そして、カスタム・イベントを設定する必要がある、何かが行われる、新しいワーク・スレッドを開始させることです。それで、ワーカー・スレッドは、アドインの進捗状況、あるいは、それが、完了したとき、知らせることができます。ワーカー・スレッドが、イベントを発生させるとき、アドインは、続いて、どこでも適切なことを行うことができる、メイン・スレッドのコントロールを取得します。
カスタム・イベント
Custom Event
Fusion APIは、スレッドの作成や管理をサポートしません。あなたは、あなたは、サポートを使用することを選択する言語のスレッディング機能を通して、行います。PythonとC++の両方は、スレッドの作成をサポートしています。しかしながら、JavaScriptは、そうではありません。それで、ここで議論されていることのほとんどは、JavaScriptでは使用できません。Fusion APIは、メイン・スレッドで実行しているあなたのアドインに、情報をやりとりするワーカー・スレッドで、実行しているコードのための方法をサポートします。これは、あなたのアドインが処理するイベントを発生するために、ワーカー・スレッドでプログラムを提供する、カスタム・イベントを通して行われます。あなたのワーカースレッドは、常に、メイン・スレッドで実行する必要があるため、Fusion内で、決して作業を行うべきではありません。
ここに、この機能が、使用するかもしれない、2つの一般的な方法を説明する、2つの例が、あります。最初のコマンドです。それは、コマンド・ダイアログを埋め込むための情報を取得するために、Webを呼び出します。Webの呼び出しは、多くの要因に依存しており、そして、かなりの時間がかかります。Webサービスとの対話は、メイン・スレッドが、コマンドの処理を継続できる別のスレッドで、実行することができます。それで、コマンド・ダイアログを、速く表示することができます。そして、その次に、Webデータが取得されたとき、コマンド・ダイアログを更新するために、メイン・スレッドで、ワーカー・スレッドから、実行しているアドインに渡すことができます。
この機能を使用する方法のもう1つの例は、何かのために、連続的に監視し、そして、その次に、特定の動作に反応して何か行う、ワーカースレッドを開始することです。例えば、アドインは、変更された場合、確かめるために、定期的に、特定のcsvファイルの変更された時間を確認する、ワーカー・スレッドを開始することを書き込むことができます。それが、持っている場合、更新されたcsvファイルを読み込み、そして、デザインで、対応するパラメータの値を更新します。この種のバックグラウンド・ポーリングは、メイン・スレッドを利用していたため、以前は使用できませんでした。
3つ目は、この機能の更に不明瞭な使い方は、互いに情報をやりとりするために2つのアドインを提供することです。それは、他のアドインのカスタム・イベントを発生するために、他のアドインが利用可能です。カスタム・イベントは、名前で識別されます。それで、名前とアドインが期待するデータの書式を知ることで、1つのアドインは、他のアドインの情報を送信することができます。この機能を利用している、興味深いアプリケーションが、開発されている場合、確かめることは面白いです。
カスタム・イベントを使用する
Using a Custom Event
概念として、カスタム・イベントを実装して、使用することは、比較的簡単です。実際には、もう少し難しいです。なぜなら、それは、どのように作成するかの理解が必要です。そして、別のスレッドとスレッディングの基本的な原則を使用します。カスタム・イベントを設定し、そして、使用する手順は、以下の一覧の通りです。
あなたのカスタム・イベントを、あなたのハンドラをイベントに登録し、そして、接続します。
- ワーク・スレッドを作成し、それを起動します。
- ワーカー・スレッドは、どんな作業でも行います。そして、アドインと共有するために、情報を持っているとき、それは、fireCustomEventメソッドを呼び出します。この結果は、Fusionで、カスタム・イベントのためのイベント・ハンドラを呼び出します。そして、提供された情報を渡します。これは、メイン・スレッドのアドインのコントロールを与えます。それで、それは、起こると思われるものは、なんでも行うことができます。
- イベントに応じる場合、アドインは、Fusionで何かを作成する、あるいは、修正しています。(いくつかの動作は、追加されるUndo操作を引き起こします)、アドインは、作業を行う前に、まず、実行中のコマンドを終了する必要があります。これは、確認するために、検証する、以下のコードを使用して、簡単に行うことができます。既定のSelectコマンドは、実行するしないにかかわらず、それは、選択コマンドを実行します。それは、現在実行中のコマンドを終了する副作用を持っています。
# 変更が作成される前に、コマンドが実行されていないことを確認してください。 if ui.activeCommand != 'SelectCommand': ui.commandDefinitions.itemById('SelectCommand').execute()
- カスタムイベントの登録を解除してクリーンアップします。
サンプルプログラム
Sample Programs
上で説明される使い方の2つを説明する、2つのサンプルがあります。最初のサンプルは、タイマーで、メインスレッドに戻る、1から15の間で乱数を送信するワーカースレッドを開始します。それは、続いて、実行中のデザインで、渡された値を使用して、「d1」という名前のパラメータを更新します。
2つ目のサンプルは、コマンド内のこの機能を使用して、情報を取得するために、コマンド・ダイアログに表示するために、説明します。それは、テーブルが含まれているダイアログでコマンドを作成します。ワーカースレッドは、定期的に、テーブルを埋め込むために使用されるメインスレッドに新しいデータを送信します。
カスタム・イベントを使用する
Using a Custom Event
知っている必要のある1つの重要な事は、カスタム・イベントを使用する場合、ワーカー・スレッド内で、あなたは、どんな、Fusion API関数も呼び出してはいけません。更に、messageBoxメソッドを呼び出すことは、ときどき、Fusionが、クラッシュする結果をもたらします。プログラムのデバッグを支援するため、あなたは、メッセージを表示する他の技術を使用することができます。例えば、以下に示すように、Windows上のPythonで、あなたは、ctypesライブラリ、そして、そのMessageBoxW関数を使用することができます。これは、あなたが、C ++から、直接、呼び出すことができるWindows MessageBoxW関数上のPythonフレンドリーなラッパです。
import ctypes
ctypes.windll.user32.MessageBoxW(None, "The message.", "Title", 1)
主な事は、メイン・スレッドのあなたのアドインによって、すべてのFusion固有の作業を実行する必要があるということです。
広告