AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein DEB DelphiEventBus vs. System.Messaging.TMessageManager
Thema durchsuchen
Ansicht
Themen-Optionen

DEB DelphiEventBus vs. System.Messaging.TMessageManager

Ein Thema von Rollo62 · begonnen am 11. Mai 2016 · letzter Beitrag vom 12. Mai 2016
Antwort Antwort
Seite 1 von 2  1 2      
Rollo62

Registriert seit: 15. Mär 2007
4.100 Beiträge
 
Delphi 12 Athens
 
#1

DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 11. Mai 2016, 19:26
Hallo zusammen,

ich würde mal gerne eure Meinung zu den Frameworks s.o. hören:
DEB: DEB
TMessageManager: http://docwiki.embarcadero.com/Libra...MessageManager

Ok, DEB nutzt womöglich Attribute um Methoden zu binden, das ist schön und modern, aber was bringt mir
das ausser etwas weniger Zeilen zu schreiben.
Auch kann DEB den ThreadType für die Synchroisation vorgeben, das ist schon interessanter.

Die machen ja prinzipiell beide Event Messaging, wobei TMessageManager orginal in Delphi/Fmx integriert ist.

Warum sollte ich da so etwas wie DEB benutzen, evtl. weil performanter oder andere Vorteile ?

Ich nutze im Moment den TMessageManager, und frage mich ob es irgendeinen Sinn macht über DEB nachzudenken.

Rollo

Geändert von Rollo62 (11. Mai 2016 um 19:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 11. Mai 2016, 20:33
Der wichtigste Vorteil ist die Möglichkeit die Nachrichten auch asynchron zu versenden.

Ein kurzer Blick in die Quellen lässt mich aber noch an der Qualität zweifeln
Da ist so einiges beim Thema Threading und Locking noch im Argen ... ist allerdings auch noch recht frisch das Projekt und schauen wir mal wie der weitere Reifeprozess vorangeht.

Interessant ist es auf jeden Fall
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.100 Beiträge
 
Delphi 12 Athens
 
#3

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 00:16
Hallo Sir Rufo,

dankesehr für deine Einschätzung.

So ähnlich sehe ich das auch, und würde nur damit anfangen wenn es einen echten Vorteil bietet.
Schliesslich schleppt man schon genug Ballast mit sich rum.
Dann werde ich erstmal bei TMessageManager bleiben, das funktioniert ja auch und ist Teil der System units.

Rollo
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 10:11
So kann man zumindest relativ leicht aus einen abgespaltenen Thread in den VCL-Mainthread senden:

Delphi-Quellcode:
unit HierKönnteDeinUnitNameStehen;

interface

uses
  System.SysUtils,
  System.Classes,
  System.Messaging;

type
  TMessageManagerHelper = class helper for TMessageManager
    procedure SendMessageToQueue(const Sender: TObject; AMessage: TMessage; ADispose: Boolean = True);
  end;

implementation

{ TMessageManagerHelper }

procedure TMessageManagerHelper.SendMessageToQueue(const Sender: TObject; AMessage: TMessage; ADispose: Boolean = True);
begin
  TThread.Queue(nil,
    procedure
    begin
      Self.SendMessage(Sender, AMessage, ADispose);
    end
    );
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.462 Beiträge
 
Delphi 12 Athens
 
#5

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 10:22
Und so geht es asynchron aus dem Hauptthread - auf Wunsch auch mit Verzögerung:

Delphi-Quellcode:
uses
  System.SysUtils,
  System.Classes,
  System.Messaging,
  System.Threading;

type
  TMessageManagerHelper = class helper for TMessageManager
    procedure SendMessageAsynch(const Sender: TObject; AMessage: TMessage; ADelayMS: Cardinal = 0; ADispose: Boolean = True); overload;
    procedure SendMessageAsynch(const Sender: TObject; AMessage: TMessage; ADispose: Boolean = True); overload;
  end;

procedure TMessageManagerHelper.SendMessageAsynch(const Sender: TObject; AMessage: TMessage; ADelayMS: Cardinal;
  ADispose: Boolean);
begin
  TTask.Run(
    procedure
    begin
      if ADelayMS > 0 then begin
        Sleep(ADelayMS);
      end;
      TThread.Queue(nil,
        Self.SendMessage(Sender, AMessage, ADelayMS);
    end);
end;

procedure TMessageManagerHelper.SendMessageAsynch(const Sender: TObject; AMessage: TMessage; ADispose: Boolean);
begin
  SendMessageAsynch(Sender, AMessage, 0, ADispose);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 10:31
@Uwe:

Das kompiliert bei mir aber nur, wenn ich den Self.SendMessage Aufruf in einer procedure verbastle:

Delphi-Quellcode:
procedure TMessageManagerHelper.SendMessageAsynch(const Sender: TObject; AMessage: TMessage; ADelayMS: Cardinal; ADispose: Boolean);
begin
  TTask.Run(
    procedure
    begin
      if ADelayMS > 0 then
      begin
        Sleep(ADelayMS);
      end;
      TThread.Queue(nil,
        procedure
        begin
          Self.SendMessage(Sender, AMessage, ADispose)
        end)
    end);
end;
Ansonsten ne schöne Idee mit der Verzögerung!
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.100 Beiträge
 
Delphi 12 Athens
 
#7

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 11:13
Dankesehr für die interessanten Vorschläge.

Ich habe mal die Frage ob man Sleep() benutzen sollte, ich meine das verwendet auf manchen Platformen ntern
Applications.ProcessMessages.
Wäre nicht ein Timer oder WaitFor sicherer ?

Ich hatte versucht mir das mit Generics in eine abgeleitete Klasse zu basteln,
damit ich noch spezifisches Payload als Parameter und Feedback als Result-Wert mit übergeben kann.

Damit kann ich dann auch anonyme Prozeduren benutzen.

Das ist zwar noch etwas unsauber und unübersichtlich, weil viel TestCode suboptimal drin ist, aber funktioniert gut und zuverlässig.

Sieht ungefähr so aus, geht sicher einfacher, und ich muss das mal aufräumen wenn Zeit ist ...

Delphi-Quellcode:
// Definiert eine universelle Message-Ableitung, mit PAyload und Feedback
type
  TMsgLink<T1, T2> = class(TMessage)
  private
    FPayload : T1;
    FFeedback : T2;

  protected

    constructor Create(const Payload : T1; const CbFkt : T2); overload;

  public

    procedure SendToSubscriber(const Sender : TObject); //(xVal : T1);

    property Payload : T1 read FPayload write FPayload;
    property Feedback : T2 read FFeedback write FFeedback;
  end;



// Definiert ein Boolean Callback, z.B. als Handled True/False
type
  TMsgFeedback_Boolean = TMsgFeedback<Boolean>;


// Definiert einen Parameter Record als PAyload für SendMEssage
type
  TMsgPayload = record
    public
      FCmd : Integer;
      FCmdSub : Integer;
      FText : String;

      procedure Setup(const iCmd, iCmdSub : Integer; sTxt: String);

    //procedure SetText(const sTxt : String);

    public

      property Cmd : Integer read FCmd write FCmd;
      property CmdSub : Integer read FCmdSub write FCmdSub;
      property Text : String read FText write FText;

  end;

// Baut alles zusammen zu einer einfachen MskLink Klasse
type
  TMsgLink_Cmd_Base = class (TMsgLink<TMsgPayload, TMsgFeedback_Boolean>)
                        constructor Create(const iCmd, iCmdSub : Integer;
                                           const strTxt : String;
                                           const fktAsw : TProc<TObject, Boolean>
                                          ); overload;

                        constructor SendMessage(const ACmp : TObject;
                                                const iCmd : Integer; iCmdSub : Integer = 0; const sTxt : String = '';
                                                const fktAsw : TProc<TObject, Boolean> = nil;
                                                bQueue : Boolean = True
                                               ); overload;

                     end;


// So kann ich verschiedene, speziele MsgLinks aufbauen, für verschiedene Aufgaben
Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.462 Beiträge
 
Delphi 12 Athens
 
#8

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 11:29
Das kompiliert bei mir aber nur, wenn ich den Self.SendMessage Aufruf in einer procedure verbastle:
Na klar! Das kommt, wenn man nach Copy-Paste das Compile vergisst...

Im Original ist das noch etwas allgemeiner gehalten:
Delphi-Quellcode:
procedure Postpone(AProc: TThreadProcedure; ADelayMS: Cardinal = 0);
begin
  TTask.Run(
    procedure
    begin
      if ADelayMS > 0 then begin
        Sleep(ADelayMS);
      end;
      TThread.Queue(nil, AProc);
    end);
end;

procedure Postpone(AProc: TThreadMethod; ADelayMS: Cardinal = 0);
begin
  TTask.Run(
    procedure
    begin
      if ADelayMS > 0 then begin
        Sleep(ADelayMS);
      end;
      TThread.Queue(nil, AProc);
    end);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 13:59
Ich hatte versucht mir das mit Generics in eine abgeleitete Klasse zu basteln,
damit ich noch spezifisches Payload als Parameter und Feedback als Result-Wert mit übergeben kann.
Du kannst auch sowas machen:

Delphi-Quellcode:
  TMyMessageContainer = class
  public
    Text: string;
    Number: Integer;
  end;

  TMyGenericMessage = System.Messaging.TMessage<TMyMessageContainer>;

  // oder noch mehr generisch:

  TMyGenericMessageContainer<T,K> = class
  public
    Prop1: T;
    Prop2: K;
  end;

  TMyMegaGenericMessage = System.Messaging.TMessage<TMyGenericMessageContainer<string, Integer>>;
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.100 Beiträge
 
Delphi 12 Athens
 
#10

AW: DEB DelphiEventBus vs. System.Messaging.TMessageManager

  Alt 12. Mai 2016, 14:47
Hallo Tigü,

ja das sieht super interessant aus, kannte ich noch gar nicht.
Mir war gar nicht aufgefallen das da schon Generics drin sind:
Zitat:
TMessage = class abstract;
TMessage<T> = class (TMessage)

Delphi-Quellcode:
  TMyMessageContainer = class
  public
    Text: string;
    Number: Integer;
  end;
Ist das jetzt eine Klasse, oder nicht ?

Wenn ja, wie wird Create und Destroy dabei aufgerufen ?
Aus besagten Gründen habe ich das als Record eingebaut.

Rollo

Geändert von Rollo62 (12. Mai 2016 um 14:51 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz