C# 在没有副作用的情况下,为可观察序列正确设置依赖谓词的功能方法是什么?
我有三个观察对象C# 在没有副作用的情况下,为可观察序列正确设置依赖谓词的功能方法是什么?,c#,system.reactive,C#,System.reactive,我有三个观察对象oGotFocusOrDocumentSaved,oGotFocus和oLostFocus。我希望oGotFocusOrDocumentSaved仅在\u active为true时推送序列。我下面的实现可以根据需要工作,但它会对\u active产生副作用。是否有办法消除副作用,但仍能获得相同的功能 class TestClass { private bool _active = true; public TestClass(..) { ... v
oGotFocusOrDocumentSaved
,oGotFocus
和oLostFocus
。我希望oGotFocusOrDocumentSaved
仅在\u active
为true时推送序列。我下面的实现可以根据需要工作,但它会对\u active
产生副作用。是否有办法消除副作用,但仍能获得相同的功能
class TestClass
{
private bool _active = true;
public TestClass(..)
{
...
var oLostFocus = Observable
.FromEventPattern<EventArgs>(_view, "LostFocus")
.Throttle(TimeSpan.FromMilliseconds(500));
var oGotFocus = Observable
.FromEventPattern<EventArgs>(_view, "GotFocus")
.Throttle(TimeSpan.FromMilliseconds(500));
var oGotFocusOrDocumentSaved = oDocumentSaved // some other observable
.Merge<CustomEvtArgs>(oGotFocus)
.Where(_ => _active)
.Publish();
var lostFocusDisposable = oLostFocus.Subscribe(_ => _active = false);
var gotFocusDisposable = oGotFocus.Subscribe(_ => _active = true);
// use case
oGotFocusOrDocumentSaved.Subscribe(x => DoSomethingWith(x));
...
}
...
}
class测试类
{
私有bool_active=true;
公共测试类(…)
{
...
var oLostFocus=可观察
.FromEventPattern(_视图,“LostFocus”)
.节气门(时间跨度从毫秒(500));
var oGotFocus=可观测
.FromEventPattern(_视图,“GotFocus”)
.节气门(时间跨度从毫秒(500));
var oGotFocusOrDocumentSaved=oDocumentSaved//其他一些可观察到的
.Merge(oGotFocus)
.Where(=>_活动)
.Publish();
var lostFocusDisposable=oLostFocus.Subscribe(\u=>\ u active=false);
var gotFocusDisposable=oGotFocus.Subscribe(\u=>\ u active=true);
//用例
oGotFocusOrDocumentSaved.Subscribe(x=>DoSomethingWith(x));
...
}
...
}
SelectMany和TakeUntil的组合应该能让你达到你需要的位置
from g in oGotFocus
from d in oDocumentSaved
.Merge<CustomEvtArgs>(oGotFocus)
.TakeUntil(oLostFocus)
来自oGotFocus中的g的
从OdoDocumentSaved中的d
.Merge(oGotFocus)
.TakeUntil(oLostFocus)
似乎您希望在保存文档时收到通知,但前提是文档当前具有焦点。对的(您还希望在文档获得焦点时收到通知,但这可以在以后轻松合并。)
用窗口而不是点事件来思考;i、 巧合地加入
您的需求可以表示为一个Join
查询,通过该查询,文档保存被连接到焦点窗口,因此仅当两者重叠时才产生通知;i、 例如,当两者都处于“活动”状态时
var oGotFocusOrDocumentSaved=
(从保存在OdoDocumentSaved中
加入oGotFocus
on Observable.Empty()//OdoDocumentSave没有持续时间
等于oLostFocus//oGotFocus持续时间持续到oLostFocus
选择(已保存)
.合并(oGotFocus);
听起来您确实想要一个oDocumentSavedWhenHasFocus
而不是一个oGotFocusOrDocumentSaved
可见的文档
因此,请尝试使用.Switch()
操作符,如下所示:
var oDocumentSavedWhenHasFocus =
oGotFocus
.Select(x => oDocumentSaved.TakeUntil(oLostFocus))
.Switch();
一旦你知道了
.Switch()
的工作原理,它的工作原理应该是显而易见的。使用=
而不是=
?你的意思是oLostFocus.Subscribe(\u=>\ u active=false)
。如果是这样,因为\u active
不会更改oGotFocusOrDocumentSaved
将始终触发事件,这不是我想要的。我的最终用例(请参见代码中)是oGotFocusOrDocumentSaved
的订阅。如果我错了,请纠正我,但在oLostFocus
开始推送其序列之前,不要执行signalOnCompleted
?我希望这个可观察到的继续,直到视图被处理。是的,这会导致内部可观察到的完成,但是下一次提出oGotFocus
时,一个全新的内部可观察到的被投影到Switch
订阅,因此外部可观察到的永远不会完成。这是实现相同目标的另一种方法。是否需要等到oGotFocus
启动时发出onCompleted
信号?我希望这个observate运行到应用程序结束,同时根据视图是否有焦点来打开/关闭。
var oDocumentSavedWhenHasFocus =
oGotFocus
.Select(x => oDocumentSaved.TakeUntil(oLostFocus))
.Switch();