AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Verständnisfrage zur Verwendung von TMessageManager im Thread
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage zur Verwendung von TMessageManager im Thread

Ein Thema von TiGü · begonnen am 29. Jul 2015 · letzter Beitrag vom 30. Jul 2015
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 11:07
Du räumst ja die Queue, wenn dort mehr als 25 Einträge enthalten sind, ok.

Gehen wir also mal davon aus, dass der erste Wert in der Queue 29.07.2015 12:00:00.000 ist.
Jetzt kommen über die IdleMessage 24 exakt die gleichen Werte an und zwar jeweils 29.07.2015 12:00:00.001.

Was passiert? Richtig, alle Werte landen in der Queue, denn alle sind ungleich dem ersten Wert in der Queue.

War es das, was du haben wolltest?
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
Online

Registriert seit: 15. Mär 2007
4.253 Beiträge
 
Delphi 12 Athens
 
#2

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 11:51
Warum machst du denn das ?

Code:
  while not Terminated do
  begin
    FLock.Enter;

    try
      TueEtwas;

    finally
      FLock.Leave;
    end;
  end;
Im Thread Execute muss man doch keine Locks setzen, nur wenn etwas synchronisiert werden müsste.
Aber die Ganze Zeit ???
  Mit Zitat antworten Zitat
TiGü

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 11:58
Warum machst du denn das ?

Code:
  while not Terminated do
  begin
    FLock.Enter;

    try
      TueEtwas;

    finally
      FLock.Leave;
    end;
  end;
Im Thread Execute muss man doch keine Locks setzen, nur wenn etwas synchronisiert werden müsste.
Aber die Ganze Zeit ???
Ich ging/gehe davon aus, dass während der Verarbeitung (im Execute) von außen neue Daten reingeschaufelt werden können (durch GetIdleMessage).
Ist mein Ansatz falsch?
In beiden Methoden wird der Datencontainer angefasst, Items hingefügt oder entfernt.
  Mit Zitat antworten Zitat
TiGü

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:13
Ich bin jetzt dazu übergegangen, mir ein Array zu übergeben.
Der Aufruf der anonymen Methode von TThread.Queue wird wahrscheinlich immer den letzten Wert für die lokale TDateTime-Variable genommen haben.
Daher die gleichen Werte in der Message.
Die gleichen Instanz-Pointer der Messages sind eher Zufall und liegen einfach nur auf der gleichen Speicheradresse.

Also war mein Problem wahrscheinlich eher ein Missverständis, wie und wann TThread.Queue die übergebenden Methoden aufruft und wie zu diesen Zeitpunkt die Werte außerhalb der anonymen Methode belegt sind.

Delphi-Quellcode:
procedure TMessageThread.DoInternalExecute;
var
  DateTimes : TArray<TDateTime>;
begin
  while not Terminated do
  begin
    try
      FLock.Enter;
      try
        if FStack.Count >= 25 then
        begin
          if not Terminated then
          begin
            DateTimes := FStack.ToArray;

            Queue(
              procedure
              begin
                DoSendMessage(DateTimes);
              end);

            FStack.Clear;
          end;
        end;
      finally
        FLock.Leave;
      end;
    finally
      Sleep(100);
    end;
  end;
end;

procedure TMessageThread.DoSendMessage(const DateTimes : TArray<TDateTime>);
var
  LMessage : TDateTimeMessage;
  LDateTime : TDateTime;
begin
  for LDateTime in DateTimes do
  begin
    LMessage := TDateTimeMessage.Create(LDateTime);
    TMessageManager.DefaultManager.SendMessage(Self, LMessage, True);
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.166 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:21
So geht der Q-Trick

Delphi-Quellcode:

  Procedure QWas(ADateTime : TDateTime);
  var
    LDateTime : TDateTime;
  begin
    LDateTime := ADateTeim;
    TThread.Queue(NIL,Procedure
     begin
       MachWasMit(LDateTime);
     end;
  end;

...
  QWas(DateTime);
...

Geändert von Mavarik (29. Jul 2015 um 13:25 Uhr)
  Mit Zitat antworten Zitat
TiGü

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:25
Hm, stimmt...das die Werte noch an der Stelle im Speicher liegen, kann keiner garantieren.

Wie macht man es richtig?
Einen Zwischenspeicher nehmen, also einen weiteren Stack/Liste als Membervariable in der eigenen TThread-Ableitung, und dort dann reinkopieren?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.166 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:27
s.o.
  Mit Zitat antworten Zitat
TiGü

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:32
So geht der Q-Trick

Delphi-Quellcode:

  Procedure QWas(ADateTime : TDateTime);
  var
    LDateTime : TDateTime;
  begin
    LDateTime := ADateTeim;
    TThread.Queue(NIL,Procedure
     begin
       MachWasMit(LDateTime);
     end;
  end;

...
  QWas(DateTime);
...
Verflucht, wie einfach hinterher immer so eine Lösung aussieht! Danke Mav!
So ist das jetzt eine runde Sache.

Delphi-Quellcode:
procedure TMessageThread.SendDateTime(const ADateTime : TDateTime);
var
  LDateTime : TDateTime;
begin
  LDateTime := ADateTime;
  TThread.Queue(nil,
    procedure
    begin
      DoSendMessage(LDateTime);
    end);
end;

procedure TMessageThread.DoInternalExecute;
begin
  while not Terminated do
  begin
    try
      FLock.Enter;
      try
        if FStack.Count >= 25 then
        begin
          if not Terminated then
          begin
            while FStack.Count <> 0 do
            begin
              SendDateTime(FStack.Pop);
            end;
          end;
        end;
      finally
        FLock.Leave;
      end;
    finally
      Sleep(100);
    end;
  end;
end;

procedure TMessageThread.DoSendMessage(const ADateTime : TDateTime);
var
  LMessage : TDateTimeMessage;
begin
  LMessage := TDateTimeMessage.Create(ADateTime);
  TMessageManager.DefaultManager.SendMessage(Self, LMessage, True);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.166 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 13:41
Abgesehen davon, dass ich keinen Thread nehmen würde...

Weil die Message ruft Dich ja auf... Es gibt also keinen Grund zu "Pollen"
  Mit Zitat antworten Zitat
TiGü

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

AW: Verständnisfrage zur Verwendung von TMessageManager im Thread

  Alt 29. Jul 2015, 11:56
War es das, was du haben wolltest?
Du meinst, dass mich der Blitz beim Scheißen treffen soll, weil ich Queue und Stack verwechselt habe?
Klar, ich will ja nach dem zuletzt hingefügten Element gucken und nicht was als allererstes hinzugefügt wurde.

Aber selbst wenn ich mein Programm (dieses Mal im Anhang) entsprechend umändere, wird DoSendMessage immer mit den gleichen TDateTime-Wert aufgerufen, obwohl laut Debugger die FItems vom Stack immer unterschiedlich sind (in der Nachkommastelle...).

Wende ich TThread.Queue falsch an? Oder muss ich die Methode DoSendMessage, die ich innerhalb der anonymen Methode aufrufe, umändern?
Angehängte Dateien
Dateityp: zip MessangerTest.zip (2,3 KB, 1x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz