Der Parameter M ist innerhalb der anonymen Methode nur bis zu ihrem Ende gültig. Der Code im Queue-Aufruf findet aber später statt (bei Synchronize ist das nicht der Fall).
Wie du schon bemerkt hast, kannst du das über eine lokale Variable lösen, die dann auch innerhalb der anonymen Queue-Methode gültig ist. Das kann anstatt der einzelnen Variablen p und i auch eine Variable vom Typ MyRecord sein.
Delphi-Quellcode:
procedure TForm1.btnEventClick(Sender: TObject);
begin
TMessageManagerClass.DefaultManager.SubscribeToMessage(MyMessage,
procedure(const Sender: TObject; const M: System.Messaging.TMessage)
var
bstr : string;
my: MyRecord;
begin
bstr := (TThread.CurrentThread.ThreadID = MainThreadID).ToString();
my := MyMessage(M).Value;
TThread.Queue(nil, procedure
begin
edtEvent.Text := my.Str + my.I.ToString + '/' + bstr + '/' + (TThread.CurrentThread.ThreadID = MainThreadID).ToString();
end);
end);
EventThread.Create();
end;