2015-12-21 1 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");

I прочитали много о сжатии, но я не знаю, какой из них мне нужно использовать. Я не знаю, есть ли больше типов, но я нашел два вида: сжатие IIS и GZip compression.

Какой я должен использовать? Если я использую сжатие GZip, нужно ли мне модифицировать мой клиент веб-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, но я не знаю, как использовать его в методе сообщения.

UPDATE 2
После @CodeCaster рекомендации я пытаюсь оптимизировать как я отправить данные на этот веб-Апи и я пишу свой собственный 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 Но есть сказал, что для повышения эффективности мне нужно будет написать Stream в StreamContent, используя JsonTextWriter.

Но я не знаю, как это сделать, потому что я не знаю, как создать экземпляр StreamContent. Все примеры, которые я видел, используют var stream, но я не вижу, как они создают экземпляр этого объекта.

Как я могу использовать JsonTextWriter для записи в поток?

+0

Сжатие фактически сделает ваше использование памяти БОЛЕЕ выше. Вам нужно будет выделить буфер для всего сообщения (которое вам нужно сделать сейчас), PLUS - буфер для сжатых данных. Предположим, что при нулевом сжатии вы получите вдвое больше памяти. – Aron

+0

@ Арон, только если вы сжимаете все в памяти, вы также можете использовать потоки, где накладные расходы будут только размером буфера. – CodeCaster

+0

@CodeCaster плюс буфер исходного потока. Это снова примерно удваивает использование вашей памяти. – Aron

ответ

0

Сжатие, о котором вы говорите, не решит вашу проблему.

Он будет только сжимать данные на уровне HTTP. Таким образом, в вашем коде вы все равно получите ту же самую, распакованную строку и тот же OutOfMemoryException, который возникает во время десериализации.

Вам необходимо изменить способ десериализации JSON. См. Incremental JSON Parsing in C#.

Редактировать: извините, я читал совсем не так. Это сериализация, а не десериализация. Тем не менее, та же проблема. Либо сама сериализация, либо инстанцирование StringContent выдает это исключение. Вам необходимо сериализовать потоковое вещание и напрямую передать поток.

Итак: используйте StreamContent, а не StringContent, и используйте JsonTextWriter для записи в поток. Таким образом, вам не нужно иметь всю сериализованную строку в памяти.

+1

Сжатие на самом деле ухудшит его проблему. – Aron

+0

Но проблема возникает, когда я сериализую список объектов. – VansFannel

+0

@ Ванс да, см. Править. Такая же разница. – CodeCaster