Don't explicitly check for Failed or Cancelled Statuses (#1179)
Between discussion at #1137 and a few rounds of revision at #1159 we arrived at an optimisation where tasks that are both heavily hit and very likely to return in a completed state are checked for a status of either RanToCompletion, Canceled or Faulted and a path is taken where no await is needed for any of those. The Canceled and Faulted tasks are returned immediately, allowing that state to be passed to the caller. However, these are exceptional cases, and if we just continued the subsequent await would raise the appropriate exception. Checking for all three cases instead of just RanToCompletion is optimising for those execptional conditions at cost (in the form of a larger comparison segment of code) to the more common cases of the task either being completed or still running. Simplify this back to a check just for RanToCompletion.
This commit is contained in:
committed by
James Newton-King
parent
3b583b886f
commit
0ef9ec292b
@@ -495,14 +495,10 @@ namespace Newtonsoft.Json
|
|||||||
_charPos++;
|
_charPos++;
|
||||||
|
|
||||||
Task<bool> task = EnsureCharsAsync(1, append, cancellationToken);
|
Task<bool> task = EnsureCharsAsync(1, append, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.RanToCompletion:
|
SetNewLine(task.Result);
|
||||||
SetNewLine(task.Result);
|
return AsyncUtils.CompletedTask;
|
||||||
return AsyncUtils.CompletedTask;
|
|
||||||
case TaskStatus.Canceled:
|
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessCarriageReturnAsync(task);
|
return ProcessCarriageReturnAsync(task);
|
||||||
|
|||||||
@@ -186,13 +186,9 @@ namespace Newtonsoft.Json
|
|||||||
private Task WriteValueInternalAsync(JsonToken token, string value, CancellationToken cancellationToken)
|
private Task WriteValueInternalAsync(JsonToken token, string value, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteValueAsync(token, cancellationToken);
|
Task task = InternalWriteValueAsync(token, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return _writer.WriteAsync(value, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return _writer.WriteAsync(value, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteValueInternalAsync(task, value, cancellationToken);
|
return WriteValueInternalAsync(task, value, cancellationToken);
|
||||||
@@ -270,13 +266,9 @@ namespace Newtonsoft.Json
|
|||||||
private Task WriteIntegerValueAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
|
private Task WriteIntegerValueAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteValueAsync(JsonToken.Integer, cancellationToken);
|
Task task = InternalWriteValueAsync(JsonToken.Integer, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return WriteDigitsAsync(uvalue, negative, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return WriteDigitsAsync(uvalue, negative, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteIntegerValueAsync(task, uvalue, negative, cancellationToken);
|
return WriteIntegerValueAsync(task, uvalue, negative, cancellationToken);
|
||||||
@@ -325,27 +317,15 @@ namespace Newtonsoft.Json
|
|||||||
internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
|
internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWritePropertyNameAsync(name, cancellationToken);
|
Task task = InternalWritePropertyNameAsync(name, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status != TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return DoWritePropertyNameAsync(task, name, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
// Completed synchronously (or very fast!), continue within this rather
|
|
||||||
// that the default branch which uses async
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DoWritePropertyNameAsync(task, name, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
|
task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return _writer.WriteAsync(':', cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return _writer.WriteAsync(':', cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return JavaScriptUtils.WriteCharAsync(task, _writer, ':', cancellationToken);
|
return JavaScriptUtils.WriteCharAsync(task, _writer, ':', cancellationToken);
|
||||||
@@ -415,13 +395,9 @@ namespace Newtonsoft.Json
|
|||||||
internal Task DoWriteStartArrayAsync(CancellationToken cancellationToken)
|
internal Task DoWriteStartArrayAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteStartAsync(JsonToken.StartArray, JsonContainerType.Array, cancellationToken);
|
Task task = InternalWriteStartAsync(JsonToken.StartArray, JsonContainerType.Array, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return _writer.WriteAsync('[', cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return _writer.WriteAsync('[', cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoWriteStartArrayAsync(task, cancellationToken);
|
return DoWriteStartArrayAsync(task, cancellationToken);
|
||||||
@@ -449,13 +425,9 @@ namespace Newtonsoft.Json
|
|||||||
internal Task DoWriteStartObjectAsync(CancellationToken cancellationToken)
|
internal Task DoWriteStartObjectAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteStartAsync(JsonToken.StartObject, JsonContainerType.Object, cancellationToken);
|
Task task = InternalWriteStartAsync(JsonToken.StartObject, JsonContainerType.Object, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return _writer.WriteAsync('{', cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return _writer.WriteAsync('{', cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoWriteStartObjectAsync(task, cancellationToken);
|
return DoWriteStartObjectAsync(task, cancellationToken);
|
||||||
@@ -505,13 +477,9 @@ namespace Newtonsoft.Json
|
|||||||
internal Task DoWriteUndefinedAsync(CancellationToken cancellationToken)
|
internal Task DoWriteUndefinedAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteValueAsync(JsonToken.Undefined, cancellationToken);
|
Task task = InternalWriteValueAsync(JsonToken.Undefined, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoWriteUndefinedAsync(task, cancellationToken);
|
return DoWriteUndefinedAsync(task, cancellationToken);
|
||||||
@@ -1086,13 +1054,9 @@ namespace Newtonsoft.Json
|
|||||||
internal Task DoWriteValueAsync(string value, CancellationToken cancellationToken)
|
internal Task DoWriteValueAsync(string value, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoWriteValueAsync(task, value, cancellationToken);
|
return DoWriteValueAsync(task, value, cancellationToken);
|
||||||
@@ -1225,13 +1189,9 @@ namespace Newtonsoft.Json
|
|||||||
internal Task WriteValueNotNullAsync(Uri value, CancellationToken cancellationToken)
|
internal Task WriteValueNotNullAsync(Uri value, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteValueNotNullAsync(task, value, cancellationToken);
|
return WriteValueNotNullAsync(task, value, cancellationToken);
|
||||||
@@ -1350,13 +1310,9 @@ namespace Newtonsoft.Json
|
|||||||
{
|
{
|
||||||
UpdateScopeWithFinishedValue();
|
UpdateScopeWithFinishedValue();
|
||||||
Task task = AutoCompleteAsync(JsonToken.Undefined, cancellationToken);
|
Task task = AutoCompleteAsync(JsonToken.Undefined, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return WriteRawAsync(json, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return WriteRawAsync(json, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoWriteRawValueAsync(task, json, cancellationToken);
|
return DoWriteRawValueAsync(task, json, cancellationToken);
|
||||||
|
|||||||
@@ -44,13 +44,9 @@ namespace Newtonsoft.Json.Linq
|
|||||||
public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
|
public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
|
||||||
{
|
{
|
||||||
Task task = writer.WritePropertyNameAsync(_name, cancellationToken);
|
Task task = writer.WritePropertyNameAsync(_name, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return WriteValueAsync(writer, cancellationToken, converters);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return WriteValueAsync(writer, cancellationToken, converters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteToAsync(task, writer, cancellationToken, converters);
|
return WriteToAsync(task, writer, cancellationToken, converters);
|
||||||
|
|||||||
@@ -381,29 +381,17 @@ namespace Newtonsoft.Json.Utilities
|
|||||||
bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)
|
bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task task = writer.WriteAsync(delimiter, cancellationToken);
|
Task task = writer.WriteAsync(delimiter, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status != TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return WriteEscapedJavaScriptStringWithDelimitersAsync(task, writer, s, delimiter, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
// Completed synchronously (or very fast!), continue within this rather
|
|
||||||
// that the default branch which uses async
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return WriteEscapedJavaScriptStringWithDelimitersAsync(task, writer, s, delimiter, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(s))
|
if (!string.IsNullOrEmpty(s))
|
||||||
{
|
{
|
||||||
task = WriteEscapedJavaScriptStringWithoutDelimitersAsync(writer, s, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
task = WriteEscapedJavaScriptStringWithoutDelimitersAsync(writer, s, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
||||||
switch (task.Status)
|
if (task.Status == TaskStatus.RanToCompletion)
|
||||||
{
|
{
|
||||||
case TaskStatus.Canceled:
|
return writer.WriteAsync(delimiter, cancellationToken);
|
||||||
case TaskStatus.Faulted:
|
|
||||||
return task;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
return writer.WriteAsync(delimiter, cancellationToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user