Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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#_System.reactive - Fatal编程技术网

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
开始推送其序列之前,不要执行signal
OnCompleted
?我希望这个可观察到的继续,直到视图被处理。是的,这会导致内部可观察到的完成,但是下一次提出
oGotFocus
时,一个全新的内部可观察到的被投影到
Switch
订阅,因此外部可观察到的永远不会完成。这是实现相同目标的另一种方法。
是否需要等到
oGotFocus
启动时发出
onCompleted
信号?我希望这个observate运行到应用程序结束,同时根据视图是否有焦点来打开/关闭。
var oDocumentSavedWhenHasFocus =
    oGotFocus
        .Select(x => oDocumentSaved.TakeUntil(oLostFocus))
        .Switch();