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++;
|
||||
|
||||
Task<bool> task = EnsureCharsAsync(1, append, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.RanToCompletion:
|
||||
SetNewLine(task.Result);
|
||||
return AsyncUtils.CompletedTask;
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
SetNewLine(task.Result);
|
||||
return AsyncUtils.CompletedTask;
|
||||
}
|
||||
|
||||
return ProcessCarriageReturnAsync(task);
|
||||
|
||||
@@ -186,13 +186,9 @@ namespace Newtonsoft.Json
|
||||
private Task WriteValueInternalAsync(JsonToken token, string value, CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteValueAsync(token, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return _writer.WriteAsync(value, cancellationToken);
|
||||
return _writer.WriteAsync(value, cancellationToken);
|
||||
}
|
||||
|
||||
return WriteValueInternalAsync(task, value, cancellationToken);
|
||||
@@ -270,13 +266,9 @@ namespace Newtonsoft.Json
|
||||
private Task WriteIntegerValueAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteValueAsync(JsonToken.Integer, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return WriteDigitsAsync(uvalue, negative, cancellationToken);
|
||||
return WriteDigitsAsync(uvalue, negative, cancellationToken);
|
||||
}
|
||||
|
||||
return WriteIntegerValueAsync(task, uvalue, negative, cancellationToken);
|
||||
@@ -325,27 +317,15 @@ namespace Newtonsoft.Json
|
||||
internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWritePropertyNameAsync(name, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status != TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
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);
|
||||
return DoWritePropertyNameAsync(task, name, cancellationToken);
|
||||
}
|
||||
|
||||
task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return _writer.WriteAsync(':', cancellationToken);
|
||||
return _writer.WriteAsync(':', cancellationToken);
|
||||
}
|
||||
|
||||
return JavaScriptUtils.WriteCharAsync(task, _writer, ':', cancellationToken);
|
||||
@@ -415,13 +395,9 @@ namespace Newtonsoft.Json
|
||||
internal Task DoWriteStartArrayAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteStartAsync(JsonToken.StartArray, JsonContainerType.Array, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return _writer.WriteAsync('[', cancellationToken);
|
||||
return _writer.WriteAsync('[', cancellationToken);
|
||||
}
|
||||
|
||||
return DoWriteStartArrayAsync(task, cancellationToken);
|
||||
@@ -449,13 +425,9 @@ namespace Newtonsoft.Json
|
||||
internal Task DoWriteStartObjectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteStartAsync(JsonToken.StartObject, JsonContainerType.Object, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return _writer.WriteAsync('{', cancellationToken);
|
||||
return _writer.WriteAsync('{', cancellationToken);
|
||||
}
|
||||
|
||||
return DoWriteStartObjectAsync(task, cancellationToken);
|
||||
@@ -505,13 +477,9 @@ namespace Newtonsoft.Json
|
||||
internal Task DoWriteUndefinedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteValueAsync(JsonToken.Undefined, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
|
||||
return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
|
||||
}
|
||||
|
||||
return DoWriteUndefinedAsync(task, cancellationToken);
|
||||
@@ -1086,13 +1054,9 @@ namespace Newtonsoft.Json
|
||||
internal Task DoWriteValueAsync(string value, CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
|
||||
return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
|
||||
}
|
||||
|
||||
return DoWriteValueAsync(task, value, cancellationToken);
|
||||
@@ -1225,13 +1189,9 @@ namespace Newtonsoft.Json
|
||||
internal Task WriteValueNotNullAsync(Uri value, CancellationToken cancellationToken)
|
||||
{
|
||||
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
|
||||
return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
|
||||
}
|
||||
|
||||
return WriteValueNotNullAsync(task, value, cancellationToken);
|
||||
@@ -1350,13 +1310,9 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
UpdateScopeWithFinishedValue();
|
||||
Task task = AutoCompleteAsync(JsonToken.Undefined, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return WriteRawAsync(json, cancellationToken);
|
||||
return WriteRawAsync(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)
|
||||
{
|
||||
Task task = writer.WritePropertyNameAsync(_name, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return WriteValueAsync(writer, cancellationToken, converters);
|
||||
return WriteValueAsync(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)
|
||||
{
|
||||
Task task = writer.WriteAsync(delimiter, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status != TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
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);
|
||||
return WriteEscapedJavaScriptStringWithDelimitersAsync(task, writer, s, delimiter, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
task = WriteEscapedJavaScriptStringWithoutDelimitersAsync(writer, s, charEscapeFlags, stringEscapeHandling, client, writeBuffer, cancellationToken);
|
||||
switch (task.Status)
|
||||
if (task.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
return task;
|
||||
case TaskStatus.RanToCompletion:
|
||||
return writer.WriteAsync(delimiter, cancellationToken);
|
||||
return writer.WriteAsync(delimiter, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user