TJson.JsonToObject <T> выдает ошибки в многопоточной среде
При использовании 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;
Это только фрагмент кода, основанный на гораздо более сложном источнике. Пока я использую этот код в одном потоке, все работает без проблем. Мне интересно, если что-то не так с кодом.
Ответы
Ответ 1
Метод TJSONUnMarshal.ObjectInstance
в REST.JsonReflect.pas
имеет серьезную ошибку:
Он вызывает FreeAndNil в экземпляре TRttiType. Это должно быть никогда, потому что все экземпляры TRtti *** управляются TRttiContext.
После того как я удалил вызов FreeAndNil, я больше не мог воспроизвести нарушение доступа.
Отмечено как: https://quality.embarcadero.com/browse/RSP-10035
P.S. Я также думаю, что https://quality.embarcadero.com/browse/RSP-9815 повлияет на ваш код.