IYielder.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. #if HAS_AWAIT
  5. using System.Security;
  6. namespace System.Linq
  7. {
  8. /// <summary>
  9. /// Interface for yielding elements to enumerator.
  10. /// </summary>
  11. /// <typeparam name="T">Type of the elements yielded to an enumerator.</typeparam>
  12. public interface IYielder<in T>
  13. {
  14. /// <summary>
  15. /// Yields a value to the enumerator.
  16. /// </summary>
  17. /// <param name="value">Value to yield return.</param>
  18. /// <returns>Awaitable object for use in an asynchronous method.</returns>
  19. IAwaitable Return(T value);
  20. /// <summary>
  21. /// Stops the enumeration.
  22. /// </summary>
  23. /// <returns>Awaitable object for use in an asynchronous method.</returns>
  24. IAwaitable Break();
  25. }
  26. class Yielder<T> : IYielder<T>, IAwaitable, IAwaiter
  27. {
  28. private readonly Action<Yielder<T>> _create;
  29. private bool _running;
  30. private bool _hasValue;
  31. private T _value;
  32. private bool _stopped;
  33. private Action _continuation;
  34. public Yielder(Action<Yielder<T>> create)
  35. {
  36. _create = create;
  37. }
  38. public IAwaitable Return(T value)
  39. {
  40. _hasValue = true;
  41. _value = value;
  42. return this;
  43. }
  44. public IAwaitable Break()
  45. {
  46. _stopped = true;
  47. return this;
  48. }
  49. public Yielder<T> GetEnumerator()
  50. {
  51. return this;
  52. }
  53. public bool MoveNext()
  54. {
  55. if (!_running)
  56. {
  57. _running = true;
  58. _create(this);
  59. }
  60. else
  61. {
  62. _hasValue = false;
  63. _continuation();
  64. }
  65. return !_stopped && _hasValue;
  66. }
  67. public T Current
  68. {
  69. get
  70. {
  71. return _value;
  72. }
  73. }
  74. public void Reset()
  75. {
  76. throw new NotSupportedException();
  77. }
  78. public IAwaiter GetAwaiter()
  79. {
  80. return this;
  81. }
  82. public bool IsCompleted
  83. {
  84. get { return false; }
  85. }
  86. public void GetResult() { }
  87. [SecurityCritical]
  88. public void UnsafeOnCompleted(Action continuation)
  89. {
  90. _continuation = continuation;
  91. }
  92. public void OnCompleted(Action continuation)
  93. {
  94. _continuation = continuation;
  95. }
  96. }
  97. }
  98. #endif