IPUB 팀이 만든 Delphi의 클래스 / 레이어 간의 커뮤니케이션을위한 스레드 안전하고 비동기식 및 단순한 메시징 시스템.
Delphi에는 자체 메시징 시스템 (System.Messaging.pas)이 잘 작동하지만 완전히 동기식이며 스레드가 안전하지 않습니다. 멀티 스레드 시스템에서 우리는 항상 다른 클래스와 통신해야하며 때로는 때로는 동기적으로, 때로는 비동기 적으로, 때로는 MainThread (UI의 경우)와 동기화되며 메시지 시스템없이 (직접 통신) 코드를 크고 복잡하게 만듭니다.
이상적인 메시징 시스템은 클래스 가이 시간 동안 특정 메시지를 듣도록 구독 한 다음 구독을 취소 할 수있는 스레드 안전 시스템이며, 메시지를받는이 청취자 클래스는 발신자가 메소드 ( 메인 ), 다른 스레드 ( ASYNC ) 및 메인 ( 배경 )에서 어떻게 동일한 스레드 (메인)에서 방법을 호출하는 방법을 알려줄 것입니다. 이것은 우리의 메시징 시스템의 기초이며, 사용법은 다른 기존 시스템 인 DEB (Delphi Event Bus)와 유사합니다.
1000 개 객체가있는 환경에서 비교를 참조하십시오.
| 구독하다 | 우편 | 구독 취소 | |
|---|---|---|---|
| iPub | 1.6368 ms | 0.1215ms | 1.7666 ms |
| 뎁 | 9.8832 ms | 2.0293 MS | 4.0022ms |
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 explicic 방법 ([vcprotected, vcpublic, vcpublished])}을 추가해야합니다.
var
LMessage: ILogOutMessage
begin
LMessage := TLogOutMessage.Create;
GMessaging.Post(LMessage);이전 예제에는 인터페이스 메시지가 표시되었지만 3 가지 유형의 메시지가 있습니다.
| 신원 | 매개 변수 |
|---|---|
| 이름 (명시 적) | 끈 |
| 매개 변수 인터페이스의 안내 (암시 적) | 인터페이스 |
| 매개 변수 인터페이스의 안내 (암시 적) + 이름 (명시 적) | 인터페이스 |
이름 ID가있는 메시지를 받으려면 메소드 속성에서 이름을 선언합니다.
[Subscribe( ' Name ' , TipMessagingThread.Main)]이름 Identity가있는 메시지를 보내려면 포스트 전화에서 알리십시오.
GMessaging.Post( ' Name ' , LMessage);참고 : 명시 적 이름은 대소 문자를 사용하지 않습니다.
[구독] 속성에서 메시지를 수신하는 메소드가 어떻게 실행되는지 결정할 수 있습니다.
| 친절한 | 설명 |
|---|---|
| tipmessagingthread.posting | 기본값, 가입자 메소드는 게시물이 호출 된 동일한 게시 스레드에서 호출됩니다. |
| tipmessagingthread.main | 가입자 메소드가 기본 스레드에서 호출됩니다. |
| tipmessagingthread.async | 가입자 메소드는 게시 스레드 이외의 새로운 anonnymous 스레드에서 비동기 적으로 호출됩니다. |
| tipmessagingthread.background | 게시 스레드가 기본 스레드 인 경우 가입자 메소드는 게시 스레드 이외의 새로운 anonnymous 스레드에서 비동기 적으로 호출됩니다. 게시 스레드가 기본 스레드가 아닌 경우 가입자 메소드는 동일한 게시 스레드에서 동기식으로 호출됩니다. |
메소드를 구독하기 위해 [가입] 속성을 사용하는 것은 매우 실용적이지만, 디자인 시간에 컴파일하기 전에 메시지의 이름을 정의해야하며 때로는 런타임에 메시지 이름을 정의하는 것이 실제로 유용하기 때문에 제한적입니다. 예를 들어, 'Product_105346_Changed'가 변경된 제품에 대한 메시지, 해당 메시지의 이름은 실행 시간에만 정의 할 수 있으므로 메시지를 수동으로들을 수있는 메소드를 구독 / 수용 할 수있는 옵션을 추가했습니다.
GMessaging.SubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged, TipMessagingThread.Posting);
GMessaging.UnsubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged);이 두 가지 수동 방법은 구독 / 구독 거부 방법과 무관합니다. [Subscribe] 속성을 사용하여 구독 메소드와 동일한 클래스와 동일한 클래스와 병합 할 수 있으며, 구독 / Unsubscribe를 호출하는 동시에 SubscribetHod / UnsbscribeMethod를 사용하여 수동으로 추가 한 메소드를 갖는 동시에 동시에이 클래스에 동시에 병합 할 수 있습니다.
수동으로 등록 방법의 또 다른 이점은 공개 방법으로만 제한하지 않는다는 것입니다 (이 문제는 RTTI Explicit Methods Directive를 사용하여 해결할 수 있습니다).
시스템에 대한 아이디어는 정보를 포함하거나 포함하지 않는 메시지, 통지, 통지를 전달하는 것입니다. 따라서 구독 메소드 내에 중지 (대기)가있는 큰 코드 또는 코드를 구독 방법 내에 표시하는 것이 좋습니다. 이는 비동기 모드에서도 시스템의 성능에 직접적인 영향을 미칩니다.
또 다른 고려 사항은 델파이의 TTASK를 사용하는 올바른 방법을 상기시키는 것입니다. TTASK를 사용하여 정지 (이벤트, 세마포어, ...)로 메소드를 실행하지 마십시오. 그 목표는 계속해서 연속적이고 간단한 작업을 수행하는 것입니다. 작업이 더 복잡하다면 올바른 것은 Tthread를 사용하는 것입니다. 시스템은 델파이의 TTASK를 사용하여 리소스를 저장하는 것 외에도 더 복잡한 환경에서 성능을 높이고 코드에서 TTASK를 잘못 사용하면 메시지를 보낼 때 응용 프로그램이 정지 될 수 있기 때문에 이에 대해 경고합니다.
iPub 메시징은 MIT에 따라 라이센스가 부여되며 라이센스 파일은이 폴더에 포함되어 있습니다.