添加认购后可观察序列 [英] Adding an observable sequence after subscription

查看:156
本文介绍了添加认购后可观察序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用的Rx监督我们的Silverlight应用程序中的活动,使我们可以在闲置一段时间后显示一条消息给用户。

我们正在转向事件(鼠标移动等)为观测值,然后合并观测,共同创造一个单一的(allActivity)观测。然后,我们扼制allActivity观察到的使用时间跨度和订阅的东西时得到通知系统已经闲置了一段时间。

我如何添加一个新的可观察/序列此认购后,(这样的认购发现这一点,没有退订和resubscribing)。

例如。合并几个序列起来,油门,认购。现在添加一个额外的序列到已经预订了可观察到的

例如code:

 私人的IObservable< D​​ateTime的> allActivity;
公共无效CreateActivityObservables(的UIElement的UIElement)
{
    //创建我们感兴趣的事件类型的IObservables和项目他们为创建DateTime对象
    //这些是可以将数据推送到用户/观察者我们的观测值序列
    //注意:这些是像在这个意义上IQueryables它们不遍历序列只是提供一种类型的IObservable
    VAR mouseMoveActivity = Observable.FromEventPattern< MouseEventHandler,MouseEventArgs>(H => uiElement.MouseMove + = H,H => uiElement.MouseMove  -  = H)
                                      。选择(O => DateTime.Now);

    VAR mouseLeftButtonActivity = Observable.FromEventPattern< MouseButtonEventHandler,MouseButtonEventArgs>(H => uiElement.MouseLeftButtonDown + = H,H => uiElement.MouseLeftButtonDown  -  = H)
                                            。选择(O => DateTime.Now);

    VAR mouseRightButtonActivity = Observable.FromEventPattern< MouseButtonEventHandler,MouseButtonEventArgs>(H => uiElement.MouseRightButtonDown + = H,H => uiElement.MouseRightButtonDown  -  = H)
                                             。选择(O => DateTime.Now);

    VAR mouseWheelActivity = Observable.FromEventPattern< MouseWheelEventHandler,MouseWheelEventArgs>(H => uiElement.MouseWheel + = H,H => uiElement.MouseWheel  -  = H)
                                       。选择(O => DateTime.Now);

    VAR keyboardActivity = Observable.FromEventPattern< KeyEventHandler,KeyEventArgs>(H => uiElement.KeyDown + = H,H => uiElement.KeyDown  -  = H)
                                     。选择(O => DateTime.Now);

    变种streetViewContainer = HtmlPage.Document.GetElementById(streetViewContainer);
        VAR的mouseMoveHandler =新的EventHandler< HtmlEventArgs>(this.Moo);
        布尔B = streetViewContainer.AttachEvent(鼠标移动的mouseMoveHandler);

    VAR browserActivity = Observable.FromEventPattern<Landmark.QDesk.ApplicationServices.IdleTimeoutService.MouseMoveHandler, HtmlEventArgs&GT;(H =&GT; this.MyMouseMove + = H,H =&GT; this.MyMouseMove  -  = H)。选择(O =&GT; DateTime.Now);

    //合并IObservables&LT; D​​ateTime的&GT;连成一个流/序列
    this.allActivity = mouseMoveActivity.Merge(mouseLeftButtonActivity)
                                        .Merge(mouseRightButtonActivity)
                                        .Merge(mouseWheelActivity)
                                        .Merge(keyboardActivity)
                                        .Merge(browserActivity);
}

公共IDisposable的订阅(时间跨度时间跨度,动作&LT; D​​ateTime的&GT; timeoutAction)
{
    的IObservable&LT; D​​ateTime的&GT; timeoutNotification = this.allActivity.Merge(IdleTimeoutService.GetDateTimeNowObservable())
                                                                .Throttle(时间跨度)
                                                                    .ObserveOn(Scheduler.ThreadPool);

    返回timeoutNotification.Subscribe(timeoutAction);
}
 

解决方案

要做到这一点是使用代替合并呼叫的中间主体的最简单方法。

 受试对象,日期时间&GT; allActivities =新的受试对象,日期时间&GT;();
VAR activitySubscriptions =新CompositeDisposable();

activitySubscriptions.Add(mouseMoveActivity.Subscribe(allActivities));
activitySubscriptions.Add(mouseLeftButtonActivity.Subscribe(allActivities));
//等等 ...

//订阅活动
allActivities.Throttle(时间跨度)
             .Subscribe(timeoutAction);

//后来再添
activitySubscriptions.Add(newActivity.Subscribe(allActivities));
 

主题类将阻止任何被认购,如果它收到任何的OnError或OnCompleted到观测的传递OnNext(进一步的OnError和OnCompleted)事件。

这种做法,您的样本之间的主要区别在于,它赞同全时创建的主体,而不是当您订阅的合并观察到的事件。由于所有在你的榜样的观测值是热的,差异不应该是明显的。

We are using Rx to monitor activity within our silverlight application so that we can display a message to the user after a period of inactivity.

We are turning events (mouse moves etc.) into observables and then merging the observables together to create a single (allActivity) observable. We then throttle the allActivity observable using a timespan and something subscribes to be notified when the system has been inactive for a period of time.

How can I add a new observable/ sequence to this after the subscription (so that the subscription picks this up without unsubscribing and resubscribing).

e.g. merge several sequences together, throttle, subscribe. Now add an additional sequence to the observable that has been subscribed to.

Example code:

private IObservable<DateTime> allActivity;
public void CreateActivityObservables(UIElement uiElement)
{
    // Create IObservables of event types we are interested in and project them as DateTimes
    // These are our observables sequences that can push data to subscribers/ observers 
    // NB: These are like IQueryables in the sense that they do not iterate over the sequence just provide an IObservable type
    var mouseMoveActivity = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => uiElement.MouseMove += h, h => uiElement.MouseMove -= h)
                                      .Select(o => DateTime.Now);

    var mouseLeftButtonActivity = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => uiElement.MouseLeftButtonDown += h, h => uiElement.MouseLeftButtonDown -= h)
                                            .Select(o => DateTime.Now);

    var mouseRightButtonActivity = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => uiElement.MouseRightButtonDown += h, h => uiElement.MouseRightButtonDown -= h)
                                             .Select(o => DateTime.Now);

    var mouseWheelActivity = Observable.FromEventPattern<MouseWheelEventHandler, MouseWheelEventArgs>(h => uiElement.MouseWheel += h, h => uiElement.MouseWheel -= h)
                                       .Select(o => DateTime.Now);

    var keyboardActivity = Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>(h => uiElement.KeyDown += h, h => uiElement.KeyDown -= h)
                                     .Select(o => DateTime.Now);

    var streetViewContainer = HtmlPage.Document.GetElementById("streetViewContainer");
        var mouseMoveHandler = new EventHandler<HtmlEventArgs>(this.Moo);
        bool b = streetViewContainer.AttachEvent("mousemove", mouseMoveHandler);

    var browserActivity = Observable.FromEventPattern<Landmark.QDesk.ApplicationServices.IdleTimeoutService.MouseMoveHandler, HtmlEventArgs>(h => this.MyMouseMove += h, h => this.MyMouseMove -= h).Select(o => DateTime.Now);

    // Merge the IObservables<DateTime> together into one stream/ sequence
    this.allActivity = mouseMoveActivity.Merge(mouseLeftButtonActivity)
                                        .Merge(mouseRightButtonActivity)
                                        .Merge(mouseWheelActivity)
                                        .Merge(keyboardActivity)
                                        .Merge(browserActivity);
}

public IDisposable Subscribe(TimeSpan timeSpan, Action<DateTime> timeoutAction)
{
    IObservable<DateTime> timeoutNotification = this.allActivity.Merge   (IdleTimeoutService.GetDateTimeNowObservable())
                                                                .Throttle(timeSpan)
                                                                    .ObserveOn(Scheduler.ThreadPool);

    return timeoutNotification.Subscribe(timeoutAction);
}

解决方案

The easiest way to do this would be to use an intermediate subject in place of the Merge calls.

Subject<DateTime> allActivities = new Subject<DateTime>();
var activitySubscriptions = new CompositeDisposable();

activitySubscriptions.Add(mouseMoveActivity.Subscribe(allActivities));
activitySubscriptions.Add(mouseLeftButtonActivity.Subscribe(allActivities));
//etc ...

//subscribe to activities
allActivities.Throttle(timeSpan)
             .Subscribe(timeoutAction);

//later add another
activitySubscriptions.Add(newActivity.Subscribe(allActivities));

The Subject class will stop passing OnNext (and further OnError and OnCompleted) events from any of the observables it is subscribed to if it receives any OnError or OnCompleted.

The main difference between this approach and your sample is that it subscribes to all the events when the subject is created, rather than when you subscribe to the merged observable. Since all of the observables in your example are hot, the difference should not be noticeable.

这篇关于添加认购后可观察序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆