public static IObservable <NameResolutionResult> ResolveHostName(DnsEndPoint endPoint, NetworkInterfaceInfo networkInterface) { Contract.Requires(endPoint != null); Contract.Requires(networkInterface != null); Contract.Ensures(Contract.Result <IObservable <NameResolutionResult> >() != null); var subject = new AsyncSubject <NameResolutionResult>(); try { DeviceNetworkInformation.ResolveHostNameAsync( endPoint, networkInterface, result => { var s = (AsyncSubject <NameResolutionResult>)result.AsyncState; s.OnNext(result); s.OnCompleted(); }, subject); } catch (Exception ex) { subject.OnError(ex); } return(subject.AsObservable()); }
/// <summary> /// Returns an observable sequence that propagates the result of the task. /// </summary> /// <typeparam name="TResult">The type of the result produced by the task.</typeparam> /// <param name="task">Task to convert to an observable sequence.</param> /// <returns>An observable sequence that produces the task's result, or propagates the exception produced by the task.</returns> /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception> /// <remarks>If the specified task object supports cancellation, consider using <see cref="Observable.FromAsync{TResult}(Func{CancellationToken, Task{TResult}})"/> instead.</remarks> public static IObservable <TResult> ToObservable <TResult>(this Task <TResult> task) { if (task == null) { throw new ArgumentNullException("task"); } /// A new class AsyncSubject appears here. /// Explanations: Represents the result of an asynchronous operation. /// Also there calls its constructor. /// Explanations: Creates a subject that can only receive one value and that value is cached for all future observations. /// Get an ImmutableList of type IObserver. var subject = new AsyncSubject <TResult>(); /// if task is completed /// case task state: RanToCompletion. Then iterate the sequence. /// case task state: Faulted /// case task state: Canceled /// else /// delay to do the task until it terminates. The function executes util parameter task generates an termination signal. if (task.IsCompleted) { ToObservableDone <TResult>(task, subject); } else { ToObservableSlow <TResult>(task, subject); } /// Variable subject is a task object, but we want an Observable object. /// Then we need a function AsObservable() defined in Observable.Single. /// Description: Hides the identity of an observable sequence. return(subject.AsObservable()); }
public static Func <IObservable <T> > ToAsync <T>(Func <T> function, IScheduler scheduler) { return(() => { var subject = new AsyncSubject <T>(); scheduler.Schedule(() => { var result = default(T); try { result = function(); } catch (Exception exception) { subject.OnError(exception); return; } subject.OnNext(result); subject.OnCompleted(); }); return subject.AsObservable(); }); }
public static IObservable <T> RaiseAsObservable <T>(this InteractionRequest <T> self, T notification) where T : INotification { var s = new AsyncSubject <T>(); self.Raise(notification, x => { s.OnNext(x); s.OnCompleted(); }); return(s.AsObservable()); }
private static IObservable <T> ToObservable <T>(this Task <T> task) { AsyncSubject <T> sbj = new AsyncSubject <T>(); task.ContinueWith(t => { switch (t.Status) { case TaskStatus.RanToCompletion: sbj.OnNext(t.Result); sbj.OnCompleted(); break; case TaskStatus.Faulted: sbj.OnError(t.Exception.InnerException); break; case TaskStatus.Canceled: sbj.OnError(new TaskCanceledException(t)); break; } }, TaskContinuationOptions.ExecuteSynchronously); sbj.SubscribeConsole(); return(sbj.AsObservable()); }
public static Func <T1, T2, IObservable <TResult> > FromAsyncPattern <T1, T2, TResult>(Func <T1, T2, AsyncCallback, object, IAsyncResult> begin, Func <IAsyncResult, TResult> end) { return((x, y) => { var subject = new AsyncSubject <TResult>(); try { begin(x, y, iar => { TResult result; try { result = end(iar); } catch (Exception exception) { subject.OnError(exception); return; } subject.OnNext(result); subject.OnCompleted(); }, null); } catch (Exception exception) { return Observable.Throw <TResult>(exception, Scheduler.DefaultSchedulers.AsyncConversions); } return subject.AsObservable(); }); }
public static Func <T, IObservable <R> > FromAsyncCallbackPattern <T, R>( this Action <T, Action <R> > call) { if (call == null) { throw new ArgumentNullException("call"); } return(t => { var subject = new AsyncSubject <R>(); try { Action <R> callback = r => { subject.OnNext(r); subject.OnCompleted(); }; call(t, callback); } catch (Exception ex) { return Observable.Throw <R>(ex, Scheduler.ThreadPool); } return subject.AsObservable <R>(); }); }
private static IObservable <TResult> ToObservableResult <TResult>(this AsyncSubject <TResult> subject, IScheduler scheduler) { if (scheduler != null) { return(subject.ObserveOn(scheduler)); } return(subject.AsObservable()); }
public static IObservable <Unit> ToObservable(this CancellationToken cancellation) { var subject = new AsyncSubject <Unit>(); cancellation.Register(() => { subject.OnNext(Unit.Default); subject.OnCompleted(); }); return(subject.AsObservable()); }
/// <summary> /// Returns an observable sequence that propagates the result of the task. /// </summary> /// <typeparam name="TResult">The type of the result produced by the task.</typeparam> /// <param name="task">Task to convert to an observable sequence.</param> /// <returns>An observable sequence that produces the task's result, or propagates the exception produced by the task.</returns> /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception> /// <remarks>If the specified task object supports cancellation, consider using <see cref="Observable.FromAsync{TResult}(Func{CancellationToken, Task{TResult}})"/> instead.</remarks> public static IObservable <TResult> ToObservable <TResult>(this Task <TResult> task) { if (task == null) { throw new ArgumentNullException("task"); } var subject = new AsyncSubject <TResult>(); switch (task.Status) { case TaskStatus.RanToCompletion: subject.OnNext(task.Result); subject.OnCompleted(); break; case TaskStatus.Faulted: subject.OnError(task.Exception.InnerException); break; case TaskStatus.Canceled: subject.OnError(new TaskCanceledException(task)); break; default: task.ContinueWith(t => { switch (t.Status) { case TaskStatus.RanToCompletion: subject.OnNext(t.Result); subject.OnCompleted(); break; case TaskStatus.Faulted: subject.OnError(t.Exception.InnerException); break; case TaskStatus.Canceled: subject.OnError(new TaskCanceledException(t)); break; } }); break; } return(subject.AsObservable()); }
public IObservable<TwitterSearchStatus> Search(string query, int page, int rpp) { var subject = new AsyncSubject<IEnumerable<TwitterSearchStatus>>(); this.service.Search(query, page, rpp, (tr, res) => { if (res.InnerException == null) { subject.OnNext(tr.Statuses); subject.OnCompleted(); } else { subject.OnError(res.InnerException); } }); return subject.AsObservable().SelectMany(r => r); }
/// <summary> /// Returns an observable sequence that propagates the result of the task. /// </summary> /// <typeparam name="TResult">The type of the result produced by the task.</typeparam> /// <param name="task">Task to convert to an observable sequence.</param> /// <returns>An observable sequence that produces the task's result, or propagates the exception produced by the task.</returns> /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception> /// <remarks>If the specified task object supports cancellation, consider using <see cref="Observable.FromAsync{TResult}(Func{CancellationToken, Task{TResult}})"/> instead.</remarks> public static IObservable <TResult> ToObservable <TResult>(this Task <TResult> task) { if (task == null) { throw new ArgumentNullException("task"); } var subject = new AsyncSubject <TResult>(); if (task.IsCompleted) { ToObservableDone <TResult>(task, subject); } else { ToObservableSlow <TResult>(task, subject); } return(subject.AsObservable()); }
/// <summary> /// Returns an observable sequence that signals when the task completes. /// </summary> /// <param name="task">Task to convert to an observable sequence.</param> /// <returns>An observable sequence that produces a unit value when the task completes, or propagates the exception produced by the task.</returns> /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception> /// <remarks>If the specified task object supports cancellation, consider using <see cref="Observable.FromAsync(Func{CancellationToken, Task})"/> instead.</remarks> public static IObservable <Unit> ToObservable(this Task task) { if (task == null) { throw new ArgumentNullException("task"); } // AsyncSubject<Unit>: Represents the result of an asynchronous operation. var subject = new AsyncSubject <Unit>(); if (task.IsCompleted) { ToObservableDone(task, subject); } else { ToObservableSlow(task, subject); } return(subject.AsObservable()); }
public static IObservable <TResult> StartAsync <TResult>(Func <CancellationToken, Task <TResult> > functionAsync, IScheduler scheduler) { var subject = new AsyncSubject <TResult>(); scheduler.Schedule(() => { var cancellable = new CancellationDisposable(); var task = default(Task <TResult>); try { task = functionAsync(cancellable.Token); } catch (Exception exception) { subject.OnError(exception); } var disp = task.ToObservable().Subscribe(subject); }); return(subject.AsObservable()); }
/// <summary> /// WebContextのログインを行う。 /// </summary> /// <param name="self"></param> /// <param name="userName">ユーザ名</param> /// <param name="password">パスワード</param> /// <returns>ユーザ情報。ログインできていない場合はnull。</returns> public static IObservable<User> LoginAsObservable(this WebContext self, string userName, string password) { // Subscribeまで処理を遅延させるためDeferでくるむ return Observable.Defer(() => { var async = new AsyncSubject<User>(); // ログインを行う var op = self.Authentication.Login(userName, password); // Completedイベントを購読して Observable.FromEvent<EventHandler, EventArgs>( h => (s, e) => h(e), h => op.Completed += h, h => op.Completed -= h) // 1回のイベント発火でイベントハンドラを解除する .Take(1) .Subscribe(_ => { // キャンセルされてたら何もせず終了 if (op.IsCanceled) { async.OnCompleted(); return; } // エラーの場合はエラー通知 if (op.HasError) { op.MarkErrorAsHandled(); async.OnError(op.Error); return; } // ユーザ情報を発行して終了。 async.OnNext(op.User as User); async.OnCompleted(); }); return async.AsObservable(); }); }
public static Func <IObservable <Unit> > ToAsync(Action action, IScheduler scheduler) { return(() => { var subject = new AsyncSubject <Unit>(); scheduler.Schedule(() => { try { action(); } catch (Exception exception) { subject.OnError(exception); return; } subject.OnNext(Unit.Default); subject.OnCompleted(); }); return subject.AsObservable(); }); }
public IObservable <Unit> Connect(IPEndPoint endPoint) { framedClient.Connect(endPoint); return(handshakeCompleted.AsObservable()); }
private static IObservable <EventPattern <TEventArgs> > FromEventBasedAsyncPattern <TDelegate, TEventArgs>( Func <EventHandler <TEventArgs>, TDelegate> conversion, Action <TDelegate> addHandler, Action <TDelegate> removeHandler, Action <object> start, Action cancel, Action canceledOrCompleted) where TEventArgs : AsyncCompletedEventArgs { Contract.Requires(conversion != null); Contract.Requires(addHandler != null); Contract.Requires(removeHandler != null); Contract.Requires(start != null); Contract.Requires(cancel != null); Contract.Requires(canceledOrCompleted != null); Contract.Ensures(Contract.Result <IObservable <EventPattern <TEventArgs> > >() != null); var subject = new AsyncSubject <EventPattern <TEventArgs> >(); TDelegate handler = default(TDelegate); object token = new object(); int isHandlerRemoved = 0, wasCanceled = 0, completed = 0; Action tryRemoveHandler = () => { if (Interlocked.Exchange(ref isHandlerRemoved, 1) == 0) { try { removeHandler(handler); } finally { canceledOrCompleted(); } } }; try { handler = conversion((sender, e) => { if (object.ReferenceEquals(e.UserState, token)) { if (Interlocked.Exchange(ref completed, 1) == 0) { try { // ensure the handler is removed in case there are no subscribers tryRemoveHandler(); } catch (Exception ex) { subject.OnError(ex); return; } if (e.Error != null) { subject.OnError(e.Error); } else { if (!e.Cancelled) { subject.OnNext(new EventPattern <TEventArgs>(sender, e)); } subject.OnCompleted(); } } } }); addHandler(handler); start(token); } catch (Exception ex) { subject.OnError(ex); return(subject.AsObservable()); } return(Observable.Create <EventPattern <TEventArgs> >( observer => new CompositeDisposable( Disposable.Create(() => { if (Interlocked.Exchange(ref completed, 1) == 0) { try { try { if (Interlocked.Exchange(ref wasCanceled, 1) == 0) { cancel(); } } finally { tryRemoveHandler(); } } catch (Exception ex) { subject.OnError(ex); } } }), subject.SubscribeSafe(observer)))); }
public static IObservable<NameResolutionResult> ResolveHostName(DnsEndPoint endPoint, NetworkInterfaceInfo networkInterface) { Contract.Requires(endPoint != null); Contract.Requires(networkInterface != null); Contract.Ensures(Contract.Result<IObservable<NameResolutionResult>>() != null); var subject = new AsyncSubject<NameResolutionResult>(); try { DeviceNetworkInformation.ResolveHostNameAsync( endPoint, networkInterface, result => { var s = (AsyncSubject<NameResolutionResult>) result.AsyncState; s.OnNext(result); s.OnCompleted(); }, subject); } catch (Exception ex) { subject.OnError(ex); } return subject.AsObservable(); }