【发布时间】:2015-04-05 03:37:59
【问题描述】:
在多线程环境中使用TJson.JsonToObject 时会发生随机访问冲突。我找了很长时间的问题,我可以用下面的代码来隔离它
JSON 类
type
TParameter = class
public
FName : string;
FDataType : string;
FValue : string;
end;
测试功能:
procedure Test();
var
myTasks: array of ITask;
i : integer;
max : integer;
begin
max := 50;
SetLength(myTasks, max);
for i := 0 to max -1 do begin
myTasks[i] := TTask.Create(procedure ()
var
json : string;
p : TParameter;
begin
json := '{"name":"NameOfParam","dataType":"TypeOfParam","value":"ValueOfParam"}';
p := TJson.JsonToObject<TParameter>(json);
p.Free;
end);
myTasks[i].Start;
end;
TTask.WaitForAll(myTasks);
ShowMessage('all done!');
end;
这只是一个基于更复杂来源的代码 sn-p。只要我在单个线程中使用此代码,一切都可以正常工作。我想知道代码是否有任何问题。
【问题讨论】:
-
哪个 JSON 库?已知它是线程安全的吗?为什么要锁定对
JsonToObject的调用。如果代码在锁的情况下运行良好,并且在没有锁的情况下失败,则表明JsonToObject不是线程安全的。 -
我无法重现此内容。只需设置一个控制台应用程序并将您的
TParameter放在一个单独的单元中似乎工作正常,没有例外。将WriteLn( TThread.CurrentThread.ThreadID );添加到您的TTask的Proc也表明反序列化发生在不同的线程中。 -
@DavidHeffernan 图书馆来自 embarcadero REST.Json
-
我认为问题出在 RTTI 上。它只是不是线程安全的。例如:stackoverflow.com/questions/27368556/… 我预计这些方面会有更多问题
-
是的,我确信存在线程安全问题。如果我序列化
TJSONUnMarshal.CreateObject的执行,那么就没有错误。我认为您需要提交错误报告。你有一个漂亮的复制品。
标签: json multithreading delphi rest delphi-xe7