Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.73 KB | None | 0 0
  1. namespace System.Collections.Generic
  2. {
  3. using System;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6.  
  7. /// <summary>
  8. /// A wrapper for a paginated, asynchronous enumerator.
  9. /// </summary>
  10. /// <typeparam name="T">the enumeration type</typeparam>
  11. public sealed class PaginatedEnumerator<T> : IAsyncEnumerator<T>
  12. {
  13. private readonly Func<int, Task<T[]>> _pageFunc;
  14. private T[] _pageItems;
  15. private int _position;
  16.  
  17. /// <summary>
  18. /// Initializes a new instance of the <see cref="PaginatedEnumerator{T}"/> class.
  19. /// </summary>
  20. /// <param name="pageFunc">the callback for asynchronously retrieving the page entries</param>
  21. public PaginatedEnumerator(Func<int, Task<T[]>> pageFunc)
  22. => _pageFunc = pageFunc ?? throw new ArgumentNullException(nameof(pageFunc));
  23.  
  24. /// <summary>
  25. /// Gets the current item.
  26. /// </summary>
  27. public T Current { get; private set; }
  28.  
  29. /// <summary>
  30. /// Gets the number of the current page.
  31. /// </summary>
  32. public int CurrentPage { get; internal set; }
  33.  
  34. /// <summary>
  35. /// Gets a value indicating whether the end has been reached.
  36. /// </summary>
  37. public bool HasReachedEnd { get; private set; }
  38.  
  39. /// <summary>
  40. /// Gets a value indicating whether any items are available or whether the next page
  41. /// should be requested.
  42. /// </summary>
  43. public bool ItemsAvailable => _pageItems != null && _position < _pageItems.Length && !HasReachedEnd;
  44.  
  45. /// <summary>
  46. /// Gets the number of items remaining in the current page.
  47. /// </summary>
  48. public int ItemsRemaining => ItemsAvailable ? _pageItems.Length - _position : 0;
  49.  
  50. /// <summary>
  51. /// Gets the number of items the current page contains.
  52. /// </summary>
  53. public int PageItemCount => _pageItems == null ? 0 : _pageItems.Length;
  54.  
  55. /// <summary>
  56. /// Does absolutely nothing.
  57. /// </summary>
  58. public void Dispose()
  59. {
  60. }
  61.  
  62. /// <summary>
  63. /// Moves to the next item asynchronously.
  64. /// </summary>
  65. /// <param name="cancellationToken">
  66. /// a cancellation token used to propagate notification that the asynchronous operation
  67. /// should be canceled.
  68. /// </param>
  69. /// <returns>
  70. /// a task that represents the asynchronous operation. The task result is a value
  71. /// indicating whether an item could be get.
  72. /// </returns>
  73. public async Task<bool> MoveNext(CancellationToken cancellationToken)
  74. {
  75. cancellationToken.ThrowIfCancellationRequested();
  76.  
  77. // check if the enumerator end has been reached and no more pages are available to enumerate.
  78. if (HasReachedEnd)
  79. {
  80. return false;
  81. }
  82.  
  83. // check if the end of the page was reached.
  84. if (_pageItems == null || _position >= _pageItems.Length)
  85. {
  86. // request the next page
  87. _pageItems = await _pageFunc(CurrentPage++);
  88.  
  89. // check if no more items are available
  90. if (_pageItems == null || _pageItems.Length == 0)
  91. {
  92. // set the flag to indicate that the end has been reached.
  93. HasReachedEnd = true;
  94.  
  95. // no items are available
  96. return false;
  97. }
  98.  
  99. // reset position
  100. _position = 0;
  101. }
  102.  
  103. // increase item position
  104. Current = _pageItems[_position++];
  105. return true;
  106. }
  107. }
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement