2015-12-21 41 views
1

我正在开发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写入流?

+0

压缩实际上会让你的内存使用率更高。您将需要为整个消息分配一个缓冲区(您现在需要这样做),为压缩数据添加一个缓冲区。假设零压缩,你将最终使用两倍的内存。 – Aron

+0

@Aron只有在你压缩内存中的所有内容时,你也可以使用流,其中开销只是缓冲区大小。 – CodeCaster

+0

@CodeCaster加上原始流的缓冲区。这又使您的内存使用量再次大幅增加一倍。 – Aron

回答

0

你所说的压缩方式不能解决你的问题。

它只会压缩HTTP级别的数据。因此,在您的代码中,您仍然会得到相同的解压缩字符串,并且在反序列化过程中出现相同的OutOfMemoryException

您需要更改如何反序列化JSON。请参阅Incremental JSON Parsing in C#

编辑:对不起,我完全读错了。这是序列化,而不是反序列化。仍然是同样的问题。序列化本身或StringContent的实例化都会引发此异常。您需要序列化它流,并直接流到输出。

所以:使用StreamContent,不StringContent,并使用JsonTextWriter写入到流中。这样你就不必在内存中拥有整个序列化的字符串。

+1

压缩实际上会让他的问题变得更糟。 – Aron

+0

但是,当我序列化对象列表时发生问题。 – VansFannel

+0

@Vans是啊,看编辑。同样的区别。 – CodeCaster

相关问题