/// <summary>
 /// Yields a new item to the receiver, and waits for the consumer to consume it.
 /// </summary>
 /// <param name="sink">The sink to receive the new item.</param>
 /// <param name="item">The new item generated.</param>
 /// <exception cref="ObjectDisposedException">The sink does not accepts items anymore.</exception>
 /// <returns>A task that completes when the yielded item has been consumed.</returns>
 public static Task YieldAndWait <T>(this IAsyncEnumerableSink <T> sink, T item)
 {
     if (sink == null)
     {
         throw new ArgumentNullException(nameof(sink));
     }
     sink.Yield(item);
     return(sink.Wait());
 }
 /// <summary>
 /// Yields new items to the receiver, and waits for the consumer to consume all of them.
 /// </summary>
 /// <param name="sink">The sink to receive the new item.</param>
 /// <param name="items">The new item generated.</param>
 /// <exception cref="ArgumentNullException"><paramref name="items"/> is <c>null</c>.</exception>
 /// <exception cref="ObjectDisposedException">The sink does not accepts items anymore.</exception>
 /// <returns>A task that completes when the yielded item has been consumed.</returns>
 public static Task YieldAndWait <T>(this IAsyncEnumerableSink <T> sink, IEnumerable <T> items)
 {
     if (sink == null)
     {
         throw new ArgumentNullException(nameof(sink));
     }
     if (sink.Yield(items))
     {
         return(sink.Wait());
     }
     return(CompletedTask);
 }
 /// <summary>
 /// Asynchronously waits for the consumer to exhaust all the yielded items.
 /// </summary>
 /// <exception cref="ObjectDisposedException">The sink does not accepts items anymore.</exception>
 /// <returns>A task that completes when the yielded item has been consumed.</returns>
 public static Task Wait <T>(this IAsyncEnumerableSink <T> sink)
 {
     return(sink.Wait(CancellationToken.None));
 }