public static IObserver <T> Create <T>(Action <T> onNext, Action <Exception> onError, Action onCompleted)
 {
     return(Observer.Create <T>(onNext, onError, onCompleted, Disposable.Empty));
 }
예제 #2
0
 public static IDisposable SubscribeWithState3 <T, TState1, TState2, TState3>(this IObservable <T> source, TState1 state1, TState2 state2, TState3 state3, Action <T, TState1, TState2, TState3> onNext, Action <Exception, TState1, TState2, TState3> onError, Action <TState1, TState2, TState3> onCompleted)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithState3Observer(state1, state2, state3, onNext, onError, onCompleted)));
 }
예제 #3
0
        /// <summary>
        /// Returns a task that will receive the last value or the exception produced by the observable sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the source sequence.</typeparam>
        /// <param name="observable">Observable sequence to convert to a task.</param>
        /// <param name="cancellationToken">Cancellation token that can be used to cancel the task, causing unsubscription from the observable sequence.</param>
        /// <param name="state">The state to use as the underlying task's AsyncState.</param>
        /// <returns>A task that will receive the last element or the exception produced by the observable sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="observable"/> is null.</exception>
        public static Task <TResult> ToTask <TResult>(this IObservable <TResult> observable,
                                                      CancellationToken cancellationToken, object state)
        {
            if (observable == null)
            {
                throw new ArgumentNullException("observable");
            }

            var hasValue  = false;
            var lastValue = default(TResult);

            var tcs = new TaskCompletionSource <TResult>(state);

            var disposable = new SingleAssignmentDisposable();

            var ctr = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() => {
                    disposable.Dispose();
                    tcs.TrySetCanceled(cancellationToken);
                });
            }

            var taskCompletionObserver = Observer.Create <TResult>(
                value => {
                hasValue  = true;
                lastValue = value;
            },
                ex => {
                tcs.TrySetException(ex);

                ctr.Dispose();     // no null-check needed (struct)
                disposable.Dispose();
            },
                () => {
                if (hasValue)
                {
                    tcs.TrySetResult(lastValue);
                }
                else
                {
                    tcs.TrySetException(new InvalidOperationException("Strings_Linq.NO_ELEMENTS"));
                }

                ctr.Dispose();     // no null-check needed (struct)
                disposable.Dispose();
            }
                );

            //
            // Subtle race condition: if the source completes before we reach the line below, the SingleAssigmentDisposable
            // will already have been disposed. Upon assignment, the disposable resource being set will be disposed on the
            // spot, which may throw an exception. (Similar to TFS 487142)
            //
            try {
                //
                // [OK] Use of unsafe Subscribe: we're catching the exception here to set the TaskCompletionSource.
                //
                // Notice we could use a safe subscription to route errors through OnError, but we still need the
                // exception handling logic here for the reason explained above. We cannot afford to throw here
                // and as a result never set the TaskCompletionSource, so we tunnel everything through here.
                //
                disposable.Disposable = observable.Subscribe/*Unsafe*/ (taskCompletionObserver);
            }
            catch (Exception ex) {
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
예제 #4
0
 public static IDisposable SubscribeWithState2 <T, TState1, TState2>(this IObservable <T> source, TState1 state1, TState2 state2, Action <T, TState1, TState2> onNext, Action <TState1, TState2> onCompleted)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithState2Observer(state1, state2, onNext, Stubs <TState1, TState2> .Throw, onCompleted)));
 }
예제 #5
0
 public static IDisposable SubscribeWithState3 <T, TState1, TState2, TState3>(this IObservable <T> source, TState1 state1, TState2 state2, TState3 state3, Action <T, TState1, TState2, TState3> onNext)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithState3Observer(state1, state2, state3, onNext, Stubs <TState1, TState2, TState3> .Throw, Stubs <TState1, TState2, TState3> .Ignore)));
 }
예제 #6
0
 public static IDisposable SubscribeWithState2 <T, TState1, TState2>(this IObservable <T> source, TState1 state1, TState2 state2, Action <T, TState1, TState2> onNext, Action <Exception, TState1, TState2> onError)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithState2Observer(state1, state2, onNext, onError, Stubs <TState1, TState2> .Ignore)));
 }
예제 #7
0
 public static IDisposable SubscribeWithState <T, TState>(this IObservable <T> source, TState state, Action <T, TState> onNext, Action <Exception, TState> onError, Action <TState> onCompleted)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithStateObserver(state, onNext, onError, onCompleted)));
 }
예제 #8
0
 public static IDisposable SubscribeWithState <T, TState>(this IObservable <T> source, TState state, Action <T, TState> onNext)
 {
     return(source.Subscribe(Observer.CreateSubscribeWithStateObserver(state, onNext, Stubs <TState> .Throw, Stubs <TState> .Ignore)));
 }
예제 #9
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext, Action <Exception> onError, Action onCompleted)
 {
     return(source.Subscribe(Observer.CreateSubscribeObserver(onNext, onError, onCompleted)));
 }
예제 #10
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext, Action onCompleted)
 {
     return(source.Subscribe(Observer.CreateSubscribeObserver(onNext, Stubs.Throw, onCompleted)));
 }