Exemple #1
0
        /// <summary>
        /// Signals the given item to the observer in a serialized fashion
        /// allowing a concurrent OnError or OnCompleted emission to be delayed until
        /// the observer.OnNext returns.
        /// Do not call OnNext from multiple threads as it may lead to ignored items.
        /// Use a full SerializedObserver wrapper for merging multiple sequences.
        /// </summary>
        /// <typeparam name="T">The element type of the observer.</typeparam>
        /// <param name="sink">The observer to signal events in a serialized fashion.</param>
        /// <param name="item">The item to signal.</param>
        /// <param name="wip">Indicates there is an emission going on currently.</param>
        /// <param name="error">The field containing an error or terminal indicator.</param>
        public static void ForwardOnNext <T>(ISink <T> sink, T item, ref int wip, ref Exception?error)
        {
            if (Interlocked.CompareExchange(ref wip, 1, 0) == 0)
            {
                sink.ForwardOnNext(item);

                if (Interlocked.Decrement(ref wip) != 0)
                {
                    var ex = error !; // NB: A concurrent OnError or OnCompleted will either set Terminated or the original exception, so never null here.
                    if (ex != ExceptionHelper.Terminated)
                    {
                        error = ExceptionHelper.Terminated;
                        sink.ForwardOnError(ex);
                    }
                    else
                    {
                        sink.ForwardOnCompleted();
                    }
                }
            }
#if !NO_TRACE
            else if (error == null)
            {
                Trace.TraceWarning("OnNext called while another OnNext call was in progress on the same Observer.");
            }
#endif
        }
Exemple #2
0
        /// <summary>
        /// Signals the given item to the observer in a serialized fashion
        /// allowing a concurrent OnError or OnCompleted emission to be delayed until
        /// the observer.OnNext returns.
        /// Do not call OnNext from multiple threads as it may lead to ignored items.
        /// Use a full SerializedObserver wrapper for merging multiple sequences.
        /// </summary>
        /// <typeparam name="T">The element type of the observer.</typeparam>
        /// <param name="sink">The observer to signal events in a serialized fashion.</param>
        /// <param name="item">The item to signal.</param>
        /// <param name="wip">Indicates there is an emission going on currently.</param>
        /// <param name="error">The field containing an error or terminal indicator.</param>
        public static void ForwardOnNext <T>(ISink <T> sink, T item, ref int wip, ref Exception error)
        {
            if (Interlocked.CompareExchange(ref wip, 1, 0) == 0)
            {
                sink.ForwardOnNext(item);
                if (Interlocked.Decrement(ref wip) != 0)
                {
                    var ex = error;
                    if (ex != ExceptionHelper.Terminated)
                    {
                        error = ExceptionHelper.Terminated;
                        sink.ForwardOnError(ex);
                    }
                    else
                    {
                        sink.ForwardOnCompleted();
                    }
                }
            }
#if (HAS_TRACE)
            else if (error == null)
            {
                Trace.TraceWarning("OnNext called while another OnNext call was in progress on the same Observer.");
            }
#endif
        }
Exemple #3
0
 /// <summary>
 /// Signals the given item to the observer in a serialized fashion
 /// allowing a concurrent OnError or OnCompleted emission to be delayed until
 /// the observer.OnNext returns.
 /// Do not call OnNext from multiple threads as it may lead to ignored items.
 /// Use a full SerializedObserver wrapper for merging multiple sequences.
 /// </summary>
 /// <typeparam name="T">The element type of the observer.</typeparam>
 /// <param name="sink">The observer to signal events in a serialized fashion.</param>
 /// <param name="item">The item to signal.</param>
 /// <param name="wip">Indicates there is an emission going on currently.</param>
 /// <param name="error">The field containing an error or terminal indicator.</param>
 public static void ForwardOnNext <T>(ISink <T> sink, T item, ref int wip, ref Exception error)
 {
     if (Interlocked.CompareExchange(ref wip, 1, 0) == 0)
     {
         sink.ForwardOnNext(item);
         if (Interlocked.Decrement(ref wip) != 0)
         {
             var ex = error;
             if (ex != ExceptionHelper.Terminated)
             {
                 error = ExceptionHelper.Terminated;
                 sink.ForwardOnError(ex);
             }
             else
             {
                 sink.ForwardOnCompleted();
             }
         }
     }
 }