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.