-Async write performance

This commit is contained in:
James Newton-King
2017-01-09 23:44:08 +13:00
parent 5fefa723ad
commit 08eb6845e2
3 changed files with 74 additions and 6 deletions
+19 -2
View File
@@ -314,9 +314,26 @@ namespace Newtonsoft.Json
return _safeAsync ? DoWritePropertyNameAsync(name, cancellationToken) : base.WritePropertyNameAsync(name, cancellationToken);
}
internal async Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
{
await InternalWritePropertyNameAsync(name, cancellationToken).ConfigureAwait(false);
Task task = InternalWritePropertyNameAsync(name, cancellationToken);
if (!task.IsCompleted)
{
return DoWritePropertyNameAsync(task, name, cancellationToken);
}
task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
if (!task.IsCompleted)
{
return JavaScriptUtils.WriteCharAsync(task, _writer, ':', cancellationToken);
}
return _writer.WriteAsync(':', cancellationToken);
}
private async Task DoWritePropertyNameAsync(Task task, string name, CancellationToken cancellationToken)
{
await task.ConfigureAwait(false);
await WriteEscapedStringAsync(name, _quoteName, cancellationToken).ConfigureAwait(false);
+21 -2
View File
@@ -41,9 +41,28 @@ namespace Newtonsoft.Json.Linq
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous write operation.</returns>
public override async Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
{
await writer.WritePropertyNameAsync(_name, cancellationToken).ConfigureAwait(false);
Task task = writer.WritePropertyNameAsync(_name, cancellationToken);
if (!task.IsCompleted)
{
return WriteToAsync(task, writer, cancellationToken, converters);
}
JToken value = Value;
if (value != null)
{
return value.WriteToAsync(writer, cancellationToken, converters);
}
else
{
return writer.WriteNullAsync(cancellationToken);
}
}
private async Task WriteToAsync(Task task, JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
{
await task.ConfigureAwait(false);
JToken value = Value;
if (value != null)
@@ -359,6 +359,11 @@ namespace Newtonsoft.Json.Utilities
#if !(NET20 || NET35 || NET40 || PORTABLE40)
public static Task WriteEscapedJavaScriptStringAsync(TextWriter writer, string s, char delimiter, bool appendDelimiters, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken = default(CancellationToken))
{
if (cancellationToken.IsCancellationRequested)
{
return cancellationToken.FromCanceled();
}
if (appendDelimiters)
{
return WriteEscapedJavaScriptStringWithDelimitersAsync(writer, s, delimiter, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
@@ -372,10 +377,31 @@ namespace Newtonsoft.Json.Utilities
return WriteEscapedJavaScriptStringWithoutDelimitersAsync(writer, s, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
}
private static async Task WriteEscapedJavaScriptStringWithDelimitersAsync(TextWriter writer, string s, char delimiter,
private static Task WriteEscapedJavaScriptStringWithDelimitersAsync(TextWriter writer, string s, char delimiter,
bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)
{
await writer.WriteAsync(delimiter).ConfigureAwait(false);
Task task = writer.WriteAsync(delimiter, cancellationToken);
if (!task.IsCompleted)
{
return WriteEscapedJavaScriptStringWithDelimitersAsync(task, writer, s, delimiter, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
}
if (!string.IsNullOrEmpty(s))
{
task = WriteEscapedJavaScriptStringWithoutDelimitersAsync(writer, s, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
if (!task.IsCompleted)
{
return WriteCharAsync(task, writer, delimiter, cancellationToken);
}
}
return writer.WriteAsync(delimiter, cancellationToken);
}
private static async Task WriteEscapedJavaScriptStringWithDelimitersAsync(Task task, TextWriter writer, string s, char delimiter,
bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)
{
await task.ConfigureAwait(false);
if (!string.IsNullOrEmpty(s))
{
@@ -385,6 +411,12 @@ namespace Newtonsoft.Json.Utilities
await writer.WriteAsync(delimiter).ConfigureAwait(false);
}
public static async Task WriteCharAsync(Task task, TextWriter writer, char c, CancellationToken cancellationToken)
{
await task.ConfigureAwait(false);
await writer.WriteAsync(c, cancellationToken).ConfigureAwait(false);
}
private static Task WriteEscapedJavaScriptStringWithoutDelimitersAsync(
TextWriter writer, string s, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling,
JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)