IPUBチームが作成したDelphiのクラス /レイヤー間の通信のための安全で非同期、単純なメッセージングシステム。
Delphiには独自のメッセージングシステム(System.messaging.pas)がありますが、うまく機能しますが、完全に同期していて安全ではありません。マルチスレッドシステムでは、常に他のクラスと通信する必要があります。時には同期して、時には非同期に、時にはMainThread(UIの場合)と同期し、メッセージシステムなしでこれを行う(直接通信)これを行うと、コードが大きく複雑で、多くのバグが生じます。
理想的なメッセージングシステムは、クラスをサブスクライブしてから登録解除してこの時期に特定のメッセージを聞くことを許可するスレッドセーフシステムであり、メッセージを受信するこのリスナークラスは、送信者がメソッドを呼び出す方法を誰に通知するかということです。これはメッセージングシステムの基礎であり、使用法は別の既存のシステムであるDelphiイベントバス(DEB)に似ています。
1000のオブジェクトを持つ環境の比較を参照してください。
| 購読する | 役職 | 登録解除 | |
|---|---|---|---|
| ipub | 1.6368ミリ秒 | 0.1215 ms | 1.7666ミリ秒 |
| デブ | 9.8832 ms | 2.0293ミリ秒 | 4.0022 ms |
ILogOutMessage = interface
[ ' {CA101646-B801-433D-B31A-ADF7F31AC59E} ' ]
// here you can put any data
end ;まず、メッセージを聴くためにクラスをサブスクライブする必要があります。次に、[サブスクライブ]属性を持つすべてのパブリックメソッドがサブスクライブされます。
TForm1 = class (TForm)
procedure FormCreate (Sender: TObject);
procedure FormDestroy (Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
[Subscribe(TipMessagingThread.Main)]
procedure OnLogout ( const AMessage: ILogOutMessage);
end ;
...
procedure TForm1.FormCreate (Sender: TObject);
begin
GMessaging.Subscribe(Self);
end ;
procedure TForm1.FormDestroy (Sender: TObject);
begin
GMessaging.Unsubscribe(Self);
end ;
procedure TForm1.OnLogout ( const AMessage: ILogOutMessage);
begin
Showmessage( ' Log out! ' );
end ;保護された部分でメソッドを宣言することもできますが、これを行うには、{$ rttiの明示的な方法([vcprotected、vcpublic、vcpublished])をクラスの前に追加する必要があります。
var
LMessage: ILogOutMessage
begin
LMessage := TLogOutMessage.Create;
GMessaging.Post(LMessage);以前の例では、インターフェイスメッセージを表示しましたが、3つのタイプのメッセージが完全にあります。
| 身元 | パラメーター |
|---|---|
| 名前(明示) | 弦 |
| パラメーターインターフェイスのガイド(暗黙的) | インタフェース |
| パラメーターインターフェイス(暗黙) +名前(明示)のガイド | インタフェース |
名前のIDを持つメッセージを受信するには、メソッド属性の名前を宣言するだけです。
[Subscribe( ' Name ' , TipMessagingThread.Main)]名前のアイデンティティを持つメッセージを送信するには、ポストコールで通知するだけです。
GMessaging.Post( ' Name ' , LMessage);注:明示的な名前はケース非感受性です。
[subscribe]属性では、メッセージを受信するメソッドがどのように実行されるかを判断できます。
| 親切 | 説明 |
|---|---|
| tipmessagingthread.posting | デフォルトでは、サブスクライバー法は、投稿が呼び出された同じ投稿スレッドで呼び出されます |
| tipmessagingthread.main | 加入者法はメインスレッドで呼び出されます |
| tipmessagingthread.async | サブスクライバー法は、投稿スレッド以外の新しい態度のスレッドで非同期に呼び出されます |
| tipmessagingthread.background | 投稿スレッドがメインスレッドである場合、サブスクライバーメソッドは、投稿スレッド以外の新しいannynemousスレッドで非同期に呼び出されます。投稿スレッドがメインスレッドではない場合、サブスクライバーメソッドは同じ投稿スレッドで同期して呼び出されます |
[subscribe]属性をサブスクライブするための使用は非常に実用的ですが、設計時にコンピレーション前にメッセージの名前を定義する必要があり、実行時にメッセージの名前を定義することが本当に便利な場合があるため、制限されています。例として、「Product_105346_Changed」を変更した製品のメッセージ、そのメッセージの名前は実行時にのみ定義できます。そのため、メッセージを手動で聞くためのメソッドをサブスクライブ /解除するオプションを追加しました。
GMessaging.SubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged, TipMessagingThread.Posting);
GMessaging.UnsubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged);これらの2つの手動方法は、購読 /登録解除方法に依存しません。 [subscribe]属性を使用して自動的にサブスクライブされたメソッドと同じクラスをマージし、subscribe / unsubscribeを呼び出します。このクラスでは、subscribeMethod / unsubscribeMethodを使用して手動で追加したメソッドを使用できます。
手動でメソッドを登録することのもう1つの利点は、パブリックメソッドのみに制限されないことです(ただし、この問題はRTTI明示的メソッド指令を使用して解決できます)。
システムのアイデアは、メッセージ、通知、情報を含む情報、または情報を転送することです。そのため、非同期モードでもシステムのパフォーマンスに直接影響するため、サブスクライブメソッド内に大規模なコードまたはコードをサブスクライブメソッド内に(WATFOR)配置することはお勧めできないことに注意してください。
別の考慮事項は、DelphiのTTASKを使用する正しい方法を思い出させることです。 TTASKを使用してストップ(イベント、セマフォなど)を実行しないでください。その目標は、タスクがより複雑である場合、継続的でよりシンプルなタスクを実行することです。私たちのシステムは、リソースの節約に加えて、より複雑な環境で主にパフォーマンスを向上させるためにDelphiのTTASKを使用しているため、これについて警告しています。コードでTTASKを誤って使用すると、メッセージを送信するときにアプリケーションをフリーズする可能性があります。
iPubメッセージングはMITの下でライセンスされ、ライセンスファイルはこのフォルダーに含まれています。