예제 #1
0
        /// <summary>
        /// Similar to (and calls) ConsumeFlow, but staunches the flow as soon as a certain droplet is found in the input flow, then starts it again.
        /// This is a piping tool and should not be used directly by consumers.
        /// </summary>
        public static async IAsyncEnumerable <bool> ConsumeFlowUntilDroplet <T>(this IFlowConsumer <T> c, IFlowProducer <T> producer, IAsyncEnumerable <T> flow, Predicate <T> stopOn)
        {
            if (producer.IsFlowStarted && producer is FlowProducerBase <T> prodImpl)
            {
                await foreach (var t in c.ConsumeFlow(Inner()))
                {
                    yield return(t);
                }
            }

            async IAsyncEnumerable <T> Inner()
            {
                await foreach (var d in flow)
                {
                    if (stopOn(d))
                    {
                        yield break;
                    }
                    yield return(d);
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Similar to (and calls) ConsumeFlow, but staunches the flow as soon as a certain droplet is found in the input flow, then starts it again.
 /// This is a piping tool and should not be used directly by consumers.
 /// </summary>
 public static IAsyncEnumerator <bool> ConsumeFlowUntilDroplet <T>(this IFlowConsumer <T> c, IFlowProducer <T> producer, IAsyncEnumerator <T> flow, Predicate <T> stopOn)
 {
     return(new AsyncEnumerator <bool>(async yield =>
     {
         if (producer.IsFlowStarted && producer is FlowProducerBase <T> prodImpl)
         {
             await c.ConsumeFlow(new AsyncEnumerator <T>(async innerYield =>
             {
                 await flow.ForEachAsync(async d =>
                 {
                     if (stopOn(d))
                     {
                         innerYield.Break();
                     }
                     await innerYield.ReturnAsync(d);
                 });
             })).UntilAsync(async b =>
             {
                 await yield.ReturnAsync(b);
                 return b;
             }, yield);
         }
     }));
 }
예제 #3
0
        /// <summary>
        /// Similar to (and calls) ConsumeFlow, but staunches the flow as soon as a predicate running on the consumer itself matches, then starts it again.
        /// This is a piping tool and should not be used directly by consumers.
        /// </summary>
        public static async IAsyncEnumerable <bool> ConsumeFlowUntil <T>(this IFlowConsumer <T> c, IFlowProducer <T> producer, IAsyncEnumerable <T> flow, Func <bool> stop)
        {
            if (producer.IsFlowStarted && producer is FlowProducerBase <T> prodImpl)
            {
                await foreach (var b in c.ConsumeFlow(Inner()))
                {
                    yield return(b);
                }
            }

            async IAsyncEnumerable <T> Inner()
            {
                await foreach (var d in flow)
                {
                    if (stop())
                    {
                        yield break;
                    }
                    yield return(d);
                }
            }
        }
예제 #4
0
 public FlowInterruptedException(IFlowProducer <T> flowProducer, string context, bool fatal, Exception inner = null)
     : base($"The flow was interrupted prematurely{(fatal ? " in a fatal way" : "")}. Context: {flowProducer.GetType().Name}::{context}", inner)
 {
     Sender = flowProducer;
     Fatal  = fatal;
 }