我必须使用哪种类型的压缩?或使用StreamContent与JsonTextWriter
我正在开发ASP.NET Web Api 2.2应用程序与.NET Framework 4.5,C#和Newtonsoft.Json 6.0.8。我必须使用哪种类型的压缩?或使用StreamContent与JsonTextWriter
我有这样的方法张贴到这个网页API:
protected bool Post<T>(string completeUri, ref T dataToPost)
{
bool result = false;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_webApiHost);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
Task<HttpResponseMessage> response = client.PostAsync(completeUri, content);
[ ... ]
}
return result;
}
当我有大量的数据要发送我来到这里的内存溢出异常:
HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
我阅读了很多关于压缩的知识,但我不知道我必须使用哪一个。我不知道是否有更多的类型,但我发现了两种:IIS压缩和GZip compression。
我必须使用哪一个?如果我使用GZip压缩,我必须修改我的web api客户端吗?
UPDATE:
我有这个类序列化,但我没有用它:
public static string Serialize(Models.Aggregations aggregation)
{
if (aggregation == null)
throw new ArgumentNullException("aggregation");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("Code");
writer.WriteValue(aggregation.Code);
if (!string.IsNullOrWhiteSpace(aggregation.Created))
{
writer.WritePropertyName("Created");
writer.WriteValue(aggregation.Created);
}
writer.WriteEndObject();
return sw.ToString();
}
如果我使用它,它会解决这个问题?我问这是因为@CodeCaster建议我使用JsonTextWriter
,但我不知道如何在我的post方法中使用它。
更新2
继@CodeCaster建议,我想我最优化如何将数据发送到网络API,我写我自己的JSON序列化这个类:
public static string Serialize(Models.Aggregations aggregation)
{
if (aggregation == null)
throw new ArgumentNullException("aggregation");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("Code");
writer.WriteValue(aggregation.Code);
if (!string.IsNullOrWhiteSpace(aggregation.Created))
{
writer.WritePropertyName("Created");
writer.WriteValue(aggregation.Created);
}
writer.WriteEndObject();
return sw.ToString();
}
但@CodeCaster有告诉我为了使效率更高,我需要使用JsonTextWriter
作为Stream写入StreamContent
。
但我不知道该怎么做,因为我不知道如何实例化StreamContent
。我见过的所有示例都使用了var stream
,但我没有看到它们是如何实例化该对象的。
如何使用JsonTextWriter写入流?
你所说的压缩方式不能解决你的问题。
它只会压缩HTTP级别的数据。因此,在您的代码中,您仍然会得到相同的解压缩字符串,并且在反序列化过程中出现相同的OutOfMemoryException
。
您需要更改如何反序列化JSON。请参阅Incremental JSON Parsing in C#。
编辑:对不起,我完全读错了。这是序列化,而不是反序列化。仍然是同样的问题。序列化本身或StringContent
的实例化都会引发此异常。您需要序列化它流,并直接流到输出。
所以:使用StreamContent
,不StringContent
,并使用JsonTextWriter
写入到流中。这样你就不必在内存中拥有整个序列化的字符串。
压缩实际上会让你的内存使用率更高。您将需要为整个消息分配一个缓冲区(您现在需要这样做),为压缩数据添加一个缓冲区。假设零压缩,你将最终使用两倍的内存。 – Aron
@Aron只有在你压缩内存中的所有内容时,你也可以使用流,其中开销只是缓冲区大小。 – CodeCaster
@CodeCaster加上原始流的缓冲区。这又使您的内存使用量再次大幅增加一倍。 – Aron