JsonConvert.DeserializeObject,索引超出数组的范围 [英] JsonConvert.DeserializeObject, Index was outside the bounds of the array

查看:206
本文介绍了JsonConvert.DeserializeObject,索引超出数组的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有这些都来自 https://github.com/JamesNK/Newtonsoft. Json/issues/469

在这里发布是因为我第一次看SO却什么都没看到,所以我发布在了该项目的GitHub页面上.

Posted here because I first looked on SO and didn't see anything, so I posted on the project's GitHub page.

我们当前正在使用JsonConvert.SerializeObjectJsonConvert.DeserializeObject<T>在客户端和服务器之间发送数据.

We're currently using JsonConvert.SerializeObject and JsonConvert.DeserializeObject<T> to send data between a client and server.

我创建了一个工具,该工具可以创建10个客户端,向10个不同的服务器发送命令,这些服务器将响应序列化并通过网络发送回去,然后这10个客户端在本地计算机上反序列化对象.

I created a tool that creates 10 clients, sends a command to 10 different servers, the servers serialize a response and send it back over the network, then the 10 clients deserialize the object on the local machine.

我正在线程池中同时运行这10个任务,并且JsonConvert.DeserializeObject调用的全部大约20%的时间因以下堆栈跟踪而失败:

I'm running these 10 tasks concurrently in the thread pool, and about 20% of the time all of the JsonConvert.DeserializeObject calls fail with the following stack trace:

Error: Index was outside the bounds of the array.
at System.Collections.Generic.List1.Add(T item)
at System.Collections.Generic.List1.System.Collections.IList.Add(Object item)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at MyClientCode()

MyClientCode()像这样使用DeserializeObject:

string json = GetServerResponse();
return JsonConvert.DeserializeObject<ResponseObject>(json);

ResponseObject很大,并且包含多个复合对象.但是,我可以保存json并使用DeserializeObject对其进行反序列化,所以我认为对象结构不是问题.

The ResponseObject is pretty big, and includes several composite objects. However, I can save the json and deserialize it properly with DeserializeObject, so I don't think the object structure is the problem.

对List错误进行研究表明,在尝试同时修改List对象时会发生这种情况.

Doing some research of the List error indicates that this occurs when trying to modify a List object concurrently.

推荐答案

来自James Newton-King:

From James Newton-King:

每次您创建一个新的JsonSerializerInternalReader 反序列化对象.每个反序列化都以其自己的状态发生. 反序列化传入JSON的高容量服务器将是 同时反序列化许多东西而没有问题.

A new JsonSerializerInternalReader is created each time you deserialize an object. Each deserialization happens in its own state. A high volume server that it deserializing incoming JSON will be deserializing many many things at the same time without issue.

我的猜测是您在同一台设备上有多个解串器 列表.

My guess is you have multiple deserializers working over the same list.


谢谢詹姆斯.深入研究后,我发现您是对的,我们在反序列化类型的多个实例中使用了相同的列表对象.具体来说,该对象看起来像这样:


Thanks James. After digging deeper I found that you're right, we were using the same list object for multiple instances of the deserialized type. Specifically, the object looked something like this:

class Obj {
    static List<string> _validSelections = new List<string>() { "One", "Two", "Three", "Four" };
    public IEnumerable<string> ValidSelections { get { return _validSelections; } }
    ... more ...
}

尝试同时向列表中添加对象时,在JsonSerializerInternalReader.cs的第1261行上引发了异常.

The exception was being thrown on line 1261 of JsonSerializerInternalReader.cs when trying to add objects to the list concurrently.

在看到我们的代码中是如何实现的之后,我将摆脱静态支持,因为它仍然无法为我们提供任何东西.

After seeing how this is implemented in our code, I am going to get rid of the static backing since it wasn't providing us anything anyway.

这篇关于JsonConvert.DeserializeObject,索引超出数组的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆