【问题标题】:TJson.JsonToObject<T> throws errors in a multi-thread environmentTJson.JsonToObject<T> 在多线程环境中抛出错误
【发布时间】: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 ); 添加到您的TTaskProc 也表明反序列化发生在不同的线程中。
  • @DavidHeffernan 图书馆来自 embarcadero REST.Json
  • 我认为问题出在 RTTI 上。它只是不是线程安全的。例如:stackoverflow.com/questions/27368556/… 我预计这些方面会有更多问题
  • 是的,我确信存在线程安全问题。如果我序列化TJSONUnMarshal.CreateObject 的执行,那么就没有错误。我认为您需要提交错误报告。你有一个漂亮的复制品。

标签: json multithreading delphi rest delphi-xe7


【解决方案1】:

REST.JsonReflect.pas中的方法TJSONUnMarshal.ObjectInstance有一个严重的bug:

它在 TRttiType 实例上调用 FreeAndNil。这应该永远不要这样做,因为所有 TRtti*** 实例都由 TRttiContext 管理。

删除 FreeAndNil 调用后,我无法再重现访问冲突。

报告为:https://quality.embarcadero.com/browse/RSP-10035

附:我也认为https://quality.embarcadero.com/browse/RSP-9815 会影响你的代码。

【讨论】:

  • 感谢您对此进行调查并报告 +1
  • 非常感谢您的努力
  • +1 和一个问题:从错误报告中不清楚是否只有通用方法调用受到影响(TJson.JsonToObject(json) - 在 XE7 应用程序中,我看到零星的 AV,它使用 TJson.JsonToObject(FSomeField, SomeJsonObject);
猜你喜欢
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多