如果我运行此代码,结果会出乎意料,因为线程中的字符串没有正确的值:
procedure TMain.FollowBose(Speakername: string; NewState: Boolean);
{..}
procedure TMain.ProcessRoomMotionResponse(Rooms: TJSONArray; Response: TJSONObject);
var
ParamName1: string;
ParamName2: string;
Room: tJSONValue;
RoomData: TJSONObject;
Roomname: string;
Motion: Boolean;
begin
if Assigned(Rooms) then begin
ParamName1 := 'Room';
ParamName2 := 'Motion';
for Room in Rooms do begin
RoomData := Room as TJSONObject;
if Assigned(RoomData.Values[ParamName1]) and Assigned(RoomData.Values[ParamName2]) then begin
Roomname := RoomData.Values[ParamName1].Value;
Motion := RoomData.Values[ParamName2].AsType<Boolean>;
LogWrite('Launching sub for ' + Roomname + '-FollowUp.', Debug);
TThread.CreateAnonymousThread(
procedure
begin
FollowUp(Roomname, Motion);
end).Start;
end;
end;
end;
end;
由于字符串很特殊,这是可以预料的吗?
这与具体的字符串无关,而是与匿名过程如何捕获变量有关。这是有记录的行为:
请参阅“匿名方法变量绑定”部分。
您与所有线程共享相同的
Roomname
和 Motion
局部变量,而不是为每个线程提供自己的变量副本。因此,当循环运行时,所有线程都会看到分配给变量的最后一个值。
试试这个:
procedure TMain.ProcessRoomMotionResponse(Rooms: TJSONArray; Response: TJSONObject);
var
ParamName1: string;
ParamName2: string;
Room: tJSONValue;
RoomData: TJSONObject;
Roomname: string;
Motion: Boolean;
procedure DoFollowUp(ARoomName: string; AMotion: Boolean);
begin
LogWrite('Launching sub for ' + ARoomName + '-FollowUp.', Debug);
TThread.CreateAnonymousThread(
procedure
begin
FollowUp(ARoomname, AMotion);
end).Start;
end;
begin
if Assigned(Rooms) then begin
ParamName1 := 'Room';
ParamName2 := 'Motion';
for Room in Rooms do begin
RoomData := Room as TJSONObject;
if Assigned(RoomData.Values[ParamName1]) and Assigned(RoomData.Values[ParamName2]) then begin
Roomname := RoomData.Values[ParamName1].Value;
Motion := RoomData.Values[ParamName2].AsType<Boolean>;
DoFollowUp(Roomname, Motion);
end;
end;
end;
end;