TJson.JsonToObject< T>在多线程环境中抛出错误 [英] TJson.JsonToObject<T> throws errors in a multi-thread environment
问题描述
在多线程环境中使用 TJson.JsonToObject
时,会发生随机访问冲突。我正在寻找很长时间的问题,我可以用以下代码隔离:
When using TJson.JsonToObject
in a multi-thread environment random access violations occur. I was searching a long time for the problem and I could isolate it with the following code
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;
这只是一个基于更复杂源代码的代码片段。只要我在一个线程中使用这个代码,一切工作都没有问题。我想知道代码是否有任何错误。
It's only a code snippet based of a much more complex source. As long I use this code in a single thread everything works without a problem. I'm wondering if there is anything wrong with the code.
推荐答案
方法 TJSONUnMarshal.ObjectInstance
REST.JsonReflect.pas
有一个严重的错误:
The method TJSONUnMarshal.ObjectInstance
in REST.JsonReflect.pas
has a severe bug:
它调用FreeAndNil TRttiType实例。这应该永远不会,因为所有TRtti ***实例都由TRttiContext管理。
It calls FreeAndNil on a TRttiType instance. This should never be done because all TRtti*** instances are managed by the TRttiContext.
在我删除FreeAndNil调用后,我无法复制访问违规。
After I removed the FreeAndNil call I could not reproduce the access violation anymore.
报告为: https:// quality .embarcadero.com / browse / RSP-10035
PS我也认为 https://quality.embarcadero.com/browse/RSP-9815 会影响您的代码。
P.S. I also think that https://quality.embarcadero.com/browse/RSP-9815 will affect your code.
这篇关于TJson.JsonToObject< T>在多线程环境中抛出错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!