Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在订阅后添加可观察序列_C#_.net_System.reactive - Fatal编程技术网

C# 在订阅后添加可观察序列

C# 在订阅后添加可观察序列,c#,.net,system.reactive,C#,.net,System.reactive,我们使用Rx监控silverlight应用程序中的活动,以便在一段时间不活动后向用户显示消息 我们正在将事件(鼠标移动等)转化为可观察对象,然后将可观察对象合并在一起,以创建单个(活动)可观察对象。然后,我们使用一个时间跨度来限制可观察到的allActivity,当系统处于非活动状态一段时间后,会有人订阅通知 我如何在订阅后向其添加新的可观察/序列(以便订阅在不取消订阅和重新订阅的情况下获取该序列) e、 把几个序列合并在一起,节流,订阅。现在向已订阅的可观察对象添加一个附加序列 示例代码: p

我们使用Rx监控silverlight应用程序中的活动,以便在一段时间不活动后向用户显示消息

我们正在将事件(鼠标移动等)转化为可观察对象,然后将可观察对象合并在一起,以创建单个(活动)可观察对象。然后,我们使用一个时间跨度来限制可观察到的allActivity,当系统处于非活动状态一段时间后,会有人订阅通知

我如何在订阅后向其添加新的可观察/序列(以便订阅在不取消订阅和重新订阅的情况下获取该序列)

e、 把几个序列合并在一起,节流,订阅。现在向已订阅的可观察对象添加一个附加序列

示例代码:

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);
}
private-IObservable-allActivity;
公共void CreateActivityObservables(UIElement UIElement)
{
//创建我们感兴趣的事件类型的IObservable,并将它们作为DateTimes进行投影
//这些是我们的可观察序列,可以将数据推送到订阅者/观察者
//注意:它们与IQueryables类似,因为它们不在序列上迭代,只提供了一个IObservable类型
var mouseMoveActivity=Observable.FromEventPattern(h=>uiElement.MouseMove+=h,h=>uiElement.MouseMove-=h)
.Select(o=>DateTime.Now);
var mouseLeftButtonActivity=Observable.FromEventPattern(h=>uiElement.MouseLeftButtonDown+=h,h=>uiElement.MouseLeftButtonDown-=h)
.Select(o=>DateTime.Now);
var mouseRightButtonActivity=Observable.FromEventPattern(h=>uiElement.MouseRightButtonDown+=h,h=>uiElement.MouseRightButtonDown-=h)
.Select(o=>DateTime.Now);
var mouseweelActivity=Observable.FromEventPattern(h=>uiElement.mouseweel+=h,h=>uiElement.mouseweel-=h)
.Select(o=>DateTime.Now);
var keyboardActivity=Observable.FromEventPattern(h=>uiElement.KeyDown+=h,h=>uiElement.KeyDown-=h)
.Select(o=>DateTime.Now);
var streetViewContainer=HtmlPage.Document.GetElementById(“streetViewContainer”);
var mouseMoveHandler=neweventhandler(this.Moo);
bool b=streetViewContainer.AttachEvent(“mousemove”,mouseMoveHandler);
var browserActivity=Observable.FromEventPattern(h=>this.MyMouseMove+=h,h=>this.MyMouseMove-=h);
//将IObservable合并到一个流/序列中
this.allActivity=mouseMoveActivity.Merge(mouseLeftButtonActivity)
.Merge(mouseRightButtonActivity)
.Merge(鼠标滚轮活动)
.合并(键盘活动)
.合并(浏览活动);
}
公共IDisposable订阅(TimeSpan TimeSpan,Action timeoutAction)
{
IObservable timeoutNotification=this.allActivity.Merge(IdleTimeoutService.GetDateTimeNowObservable())
.节气门(时间跨度)
.ObserveOn(调度程序线程池);
返回timeoutNotification.Subscribe(timeoutAction);
}

最简单的方法是使用中间主题代替
合并调用

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));
Subject allActivities=新主题();
var activitySubscriptions=new CompositeDisposable();
activitySubscriptions.Add(mouseMoveActivity.Subscribe(allActivities));
activitySubscriptions.Add(mouseLeftButtonActivity.Subscribe(allActivities));
//等等。。。
//订阅活动
所有活动。节气门(时间跨度)
.订阅(超时操作);
//稍后再添加一个
activitySubscriptions.Add(newActivity.Subscribe(allActivities));
Subject
类将停止从订阅的任何观察对象传递OnNext(以及更多的OnError和OnCompleted)事件,如果它收到任何OnError或OnCompleted


此方法与示例之间的主要区别在于,它在创建主题时订阅所有事件,而不是在订阅合并的可观察对象时订阅。由于您的示例中的所有可观察对象都是热的,因此差异不应该是明显的。

有一个需要合并的重载,它接受一个IObservable。将外部序列设为主题,并在需要向该串添加其他源时调用OnNext。合并运算符将接收源并订阅它:

var xss = new Subject<IObservable<int>>();
xss.Merge().Subscribe(x => Console.WriteLine(x));

xss.OnNext(Observable.Interval(TimeSpan.FromSeconds(1.0)).Select(x => 23 + 8 * (int)x));
xss.OnNext(Observable.Interval(TimeSpan.FromSeconds(0.8)).Select(x => 17 + 3 * (int)x));
xss.OnNext(Observable.Interval(TimeSpan.FromSeconds(1.3)).Select(x => 31 + 2 * (int)x));
...
var xss=newsubject();
xss.Merge().Subscribe(x=>Console.WriteLine(x));
xss.OnNext(可观测的时间间隔(TimeSpan.FromSeconds(1.0)).Select(x=>23+8*(int)x));
xss.OnNext(可观测的时间间隔(时间跨度从秒(0.8))选择(x=>17+3*(int)x));
xss.OnNext(可观测的时间间隔(TimeSpan.FromSeconds(1.3))。选择(x=>31+2*(int)x));
...

你好,吉迪恩,谢谢你。您的答案(使用主题)与Dave Sexton在以下论坛上提供的答案非常相似(我已经测试了Dave的解决方案,似乎效果很好):@user1040208我看到的一个区别是Dave的版本将订阅每个观察者的源观测值,而我的版本只有一个(主题)不管有多少观察员。对于这种用法,这应该没什么大不了的,但如果这种方法在其他地方使用,那么值得注意。非常高兴您能在这里回答问题。期待更多。