如何在使用Switch语句时处置内部observable

时间:2016-01-26 12:01:47

标签: c# .net system.reactive

我有一个嵌套的IObservable,我正在使用Rx的switch语句,这有助于我处理以前的序列。但是如果我想手动处理怎么办?处置外部序列不是一种选择。

_performSearchSubject
.Select(_ => return PerformQuery())
            .Switch()
            .Subscribe(HandleResponseStream, HandleError);

PerformQuery返回IObservable<Result>;

2 个答案:

答案 0 :(得分:4)

过了一段时间我自己找到了...所以答案是:

您可以使用TakeUntil(IObservable<TOther>),然后只需传入一个新主题,只要您想取消上一个流,就可以调用该主题。我认为它类似于Switch()语句在底层流中的作用。

最终代码看起来像这样:

Subject<Unit> _cancellationObservable = new Subject<Unit>();

_performSearchSubject
.Select(_ => {
                return PerformQuery().TakeUntil(_cancellationObservable);
              })
            .Switch()
            .Subscribe(HandleResponseStream, HandleError);

每当我想要取消它时,我就叫这个人:

_cancellationObservable.OnNext(Unit.Default);

答案 1 :(得分:0)

“PerformQuery”返回的Observable流将在以下任何一个时间自动处理:

  • 由于新的'_performSearchSubject',您的'Switch'语句会执行。即,“Switch”操作员将清除前一个流。 OR
  • 您的整体查询已被处理。

您应该存储.Subscribe退回的一次性用品,并使用它来清理您的订阅。您不必使用内部主题。

您是否真的尝试过原始解决方案? 以下是一些Linqpad代码来证明这一点:

var inner = Observable.Create<string>((o) =>
{
    o.OnNext("First item of new inner");
    return Disposable.Create(() => "Inner Disposed".Dump());
});

var outer = Observable.Timer(TimeSpan.MinValue, TimeSpan.FromSeconds(10))
        .Select(_ => inner)
        .Switch()
        .Subscribe(output => output.Dump());


Console.ReadLine();

outer.Dispose();

您会注意到,无论您何时按下某个键并进入(通过Console.ReadLine),您的内部可观察流将被处理掉。同样,每次Timer触发时,Switch语句都会清除所有以前的流。

如果您希望根据不相关的流控制它,您仍然可以使用'TakeUntil',但是,如果可以的话,最好只使用一次性重新设置。