Einzelnen Beitrag anzeigen

j.zT

Registriert seit: 12. Nov 2024
2 Beiträge
 
#1

Variable eines Record geht beim Multithreading verloren

  Alt 28. Nov 2024, 12:05
Delphi-Version: 12 Athens
Hallo,
ich versuche mich gerade am Multithreading mit delphi und bin gerade auf ein seltsames Verhalten gestoßen, dass ich nicht verstehe.
Ich habe derzeit folgenden Code:

Delphi-Quellcode:
procedure TForm1.btnEventClick(Sender: TObject);
begin
  TMessageManagerClass.DefaultManager.SubscribeToMessage(MyMessage,
  procedure(const Sender: TObject; const M: System.Messaging.TMessage)
  var
    bstr : string;
    p : string;
    i : string;
  begin
    bstr := (TThread.CurrentThread.ThreadID = MainThreadID).ToString();

    p := MyMessage(M).Value.Str;
    i := MyMessage(M).Value.I.ToString();

// TThread.Queue(nil, procedure
// begin
// edtEvent.Text := p + i + '/' + bstr + '/' + (TThread.CurrentThread.ThreadID = MainThreadID).ToString();
// end);

    TThread.Queue(nil, procedure
    begin
      edtEvent.Text := MyMessage(M).Value.Str + MyMessage(M).Value.I.ToString() + '/' + bstr + '/' + (TThread.CurrentThread.ThreadID = MainThreadID).ToString();
    end);
  end);

  EventThread.Create();
end;
Delphi-Quellcode:
  MyRecord = record
    Str: string;
    I: Integer;
  end;

  MyMessage = class(TMessage<MyRecord>)
  end;

  EventThread = class(TThread)
  protected
    procedure Execute; override;
  end;

Delphi-Quellcode:
procedure EventThread.Execute;
var
  rec : MyRecord;
begin
  while True do
  begin
    rec.str := Chr(ord('a') + Random(26));
    rec.I := Random(9);

    TMessageManager.DefaultManager.SendMessage(self, MyMessage.Create(rec));

    Sleep(1000);
  end;
end;
Ich sehe in der Variable p, dass ein zufälliger Buchstabe in dem string steht. Wenn der Code dann aber im TThread.Queue ankommt, dann ist MyMessage(M).Value.Str = ''.
Wenn ich in TThread.Queue aber auf die Variable p direkt zugreife (siehe auskommentierter Code), dann ist der Char wie erwartet im edit zu sehen.

Kann mir jemand erklären, warum das so passiert?

Edit 1:
Ich habe das ganze mit Synchronize getestet. Hier ist es egal, ob ich den String in einer Variablen zwischenspeichere, oder direkt aus dem Record auslese. In beiden Fällen wird der Char in den Edit geschrieben.

Geändert von j.zT (28. Nov 2024 um 12:26 Uhr)
  Mit Zitat antworten Zitat