You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
4.5 KiB

  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. #if HAVE_ASYNC
  26. using System.Diagnostics;
  27. using System.IO;
  28. using System.Threading;
  29. using System.Threading.Tasks;
  30. namespace Newtonsoft.Json.Utilities
  31. {
  32. internal static class AsyncUtils
  33. {
  34. // Pre-allocate to avoid wasted allocations.
  35. public static readonly Task<bool> False = Task.FromResult(false);
  36. public static readonly Task<bool> True = Task.FromResult(true);
  37. internal static Task<bool> ToAsync(this bool value) => value ? True : False;
  38. public static Task CancelIfRequestedAsync(this CancellationToken cancellationToken)
  39. {
  40. return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : null;
  41. }
  42. public static Task<T> CancelIfRequestedAsync<T>(this CancellationToken cancellationToken)
  43. {
  44. return cancellationToken.IsCancellationRequested ? FromCanceled<T>(cancellationToken) : null;
  45. }
  46. // From 4.6 on we could use Task.FromCanceled(), but we need an equivalent for
  47. // previous frameworks.
  48. public static Task FromCanceled(this CancellationToken cancellationToken)
  49. {
  50. Debug.Assert(cancellationToken.IsCancellationRequested);
  51. return new Task(() => {}, cancellationToken);
  52. }
  53. public static Task<T> FromCanceled<T>(this CancellationToken cancellationToken)
  54. {
  55. Debug.Assert(cancellationToken.IsCancellationRequested);
  56. return new Task<T>(() => default(T), cancellationToken);
  57. }
  58. // Task.Delay(0) is optimised as a cached task within the framework, and indeed
  59. // the same cached task that Task.CompletedTask returns as of 4.6, but we'll add
  60. // our own cached field for previous frameworks.
  61. internal static readonly Task CompletedTask = Task.Delay(0);
  62. public static Task WriteAsync(this TextWriter writer, char value, CancellationToken cancellationToken)
  63. {
  64. Debug.Assert(writer != null);
  65. return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value);
  66. }
  67. public static Task WriteAsync(this TextWriter writer, string value, CancellationToken cancellationToken)
  68. {
  69. Debug.Assert(writer != null);
  70. return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value);
  71. }
  72. public static Task WriteAsync(this TextWriter writer, char[] value, int start, int count, CancellationToken cancellationToken)
  73. {
  74. Debug.Assert(writer != null);
  75. return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value, start, count);
  76. }
  77. public static Task<int> ReadAsync(this TextReader reader, char[] buffer, int index, int count, CancellationToken cancellationToken)
  78. {
  79. Debug.Assert(reader != null);
  80. return cancellationToken.IsCancellationRequested ? FromCanceled<int>(cancellationToken) : reader.ReadAsync(buffer, index, count);
  81. }
  82. public static bool IsCompletedSucessfully(this Task task)
  83. {
  84. // IsCompletedSucessfully is the faster method, but only currently exposed on .NET Core 2.0
  85. #if NETCOREAPP2_0
  86. return task.IsCompletedSucessfully;
  87. #else
  88. return task.Status == TaskStatus.RanToCompletion;
  89. #endif
  90. }
  91. }
  92. }
  93. #endif