Thread Safe, Sistem Pesan Asynchronous dan Simplistic untuk Komunikasi antara kelas / lapisan di Delphi yang dibuat oleh tim IPUB.
Delphi memiliki sistem pesannya sendiri (System.messaging.pas) yang bekerja dengan baik tetapi benar -benar sinkron dan utas tidak aman. Dalam sistem multithreaded kita selalu perlu berkomunikasi dengan kelas lain, kadang -kadang secara sinkron, kadang -kadang tidak sinkron, kadang -kadang disinkronkan dengan mainthread (dalam kasus UI), dan melakukan ini tanpa sistem pesan (berkomunikasi secara langsung) membuat kode ini besar dan kompleks, rentan terhadap banyak bug.
Sistem pesan yang ideal akan menjadi sistem yang aman utas yang akan memungkinkan kelas untuk berlangganan dan kemudian berhenti berlangganan untuk mendengarkan pesan tertentu selama ini, dan kelas pendengar yang akan menerima pesan ini adalah siapa yang akan menginformasikan bagaimana pengirim akan memohon metode: pada utas yang sama ( posting ), di utas utama ), di utas lain ( async ) dan di utas lain dari lain dari latar belakang ). Ini adalah dasar dari sistem pesan kami, penggunaannya mirip dengan sistem lain yang ada, Delphi Event Bus (DEB).
Lihat perbandingan dalam lingkungan dengan 1000 objek:
| Berlangganan | Pos | Berhenti berlangganan | |
|---|---|---|---|
| ipub | 1.6368 ms | 0,1215 ms | 1.7666 ms |
| Deb | 9.8832 ms | 2.0293 ms | 4.0022 ms |
ILogOutMessage = interface
[ ' {CA101646-B801-433D-B31A-ADF7F31AC59E} ' ]
// here you can put any data
end ;Pertama, Anda harus berlangganan kelas Anda untuk mendengarkan pesan, maka semua metode publik yang memiliki atribut [berlangganan] akan berlangganan.
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 ;Anda juga dapat mendeklarasikan metode dalam bagian yang dilindungi, tetapi untuk melakukan ini Anda perlu menambahkan {$ rtti metode eksplisit ([vcProtected, vcpublic, vcpublished])} sebelum kelas.
var
LMessage: ILogOutMessage
begin
LMessage := TLogOutMessage.Create;
GMessaging.Post(LMessage);Dalam contoh sebelumnya kami telah menunjukkan pesan antarmuka, tetapi ada 3 jenis pesan:
| Identitas | Parameter |
|---|---|
| nama (eksplisit) | rangkaian |
| Panduan Antarmuka Parameter (Implisit) | antarmuka |
| GUID OF PARAMETER INTERFACE (Implisit) + Nama (Eksplisit) | antarmuka |
Untuk menerima pesan dengan identitas nama, cukup nyatakan atribut nama dalam metode:
[Subscribe( ' Name ' , TipMessagingThread.Main)]Untuk mengirim pesan dengan identitas nama, informasikan saja di panggilan pos:
GMessaging.Post( ' Name ' , LMessage);Catatan: Nama eksplisit tidak peka.
Dalam atribut [berlangganan], Anda dapat menentukan bagaimana metode yang menerima pesan akan dieksekusi:
| Baik | Keterangan |
|---|---|
| TipMessagingThread.posting | Default, metode pelanggan akan dipanggil di utas posting yang sama di mana pos dipanggil |
| TipMessagingThread.Main | Metode pelanggan akan dipanggil di utas utama |
| TipMessagingThread.async | Metode Pelanggan akan dipanggil secara tidak sinkron di utas Anonnymous baru selain dari utas posting |
| TipMessagingThread.Background | Jika utas posting adalah utas utama, metode pelanggan akan dipanggil secara tidak sinkron dalam utas anonnymous baru, selain utas posting. Jika utas posting bukan utas utama, metode pelanggan akan dipanggil secara sinkron di utas posting yang sama |
Meskipun penggunaan atribut [berlangganan] untuk berlangganan metode sangat praktis, itu terbatas karena Anda harus mendefinisikan nama pesan sebelum kompilasi, dalam waktu desain, dan kadang -kadang sangat berguna untuk menentukan nama pesan dalam runtime. Contoh, pesan untuk produk yang telah diubah 'Product_105346_Changed', nama pesan itu yang hanya dapat saya definisikan pada saat lari, jadi kami menambahkan opsi untuk berlangganan / berhenti berlangganan metode untuk mendengarkan pesan secara manual:
GMessaging.SubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged, TipMessagingThread.Posting);
GMessaging.UnsubscribeMethod<string>( ' product_105346_changed ' , Self.OnProductChanged);Dua metode manual ini tidak tergantung pada metode berlangganan / berhenti berlangganan. Anda dapat menggabungkan kelas yang sama dengan metode berlangganan secara otomatis menggunakan atribut [berlangganan] dan memanggil berlangganan / berhenti berlangganan, dan pada saat yang sama di kelas ini memiliki metode yang Anda tambahkan secara manual menggunakan SubscribeMethod / UnsubscribeMethod.
Manfaat lain dari metode yang mendaftar secara manual adalah bahwa mereka tidak membatasi hanya metode publik (meskipun masalah ini dapat diselesaikan dengan menggunakan arahan metode eksplisit RTTI).
Gagasan sistem ini hanya untuk meneruskan pesan, pemberitahuan, berisi atau tidak informasi, jadi perlu diingat bahwa tidak disarankan untuk menempatkan kode besar atau kode dengan berhenti (tunggu) dalam metode yang berlangganan untuk mendengarkan pesan, karena ini akan secara langsung mempengaruhi kinerja sistem, bahkan dalam mode yang tidak sinkron.
Pertimbangan lain hanyalah pengingat cara yang benar untuk menggunakan ttik delphi. Jangan pernah menggunakan TTASK untuk menjalankan metode dengan berhenti (peristiwa, semaphores, ...), itu tidak dibuat untuk itu, tujuannya adalah melakukan tugas yang berkelanjutan dan lebih sederhana, jika tugas Anda lebih kompleks, hal yang benar adalah menggunakan TTHREAD. Kami memperingatkan Anda tentang hal ini, karena sistem kami menggunakan TTASK Delphi untuk meningkatkan kinerja terutama di lingkungan yang lebih kompleks selain menghemat sumber daya, dan jika Anda menggunakan TTASK secara tidak benar dalam kode Anda, Anda dapat menyebabkan aplikasi Anda membeku saat mengirim pesan.
Pesan IPUB dilisensikan di bawah MIT, dan file lisensi termasuk dalam folder ini.