Concurrency 是否可以在“取消订阅”后在RxJava中运行后台操作?

Concurrency 是否可以在“取消订阅”后在RxJava中运行后台操作?,concurrency,rx-java,Concurrency,Rx Java,在解脚本后是否可以在rxJava中运行后台操作 例如:我创建了一个由3个字符串组成的流:a、B、C,我为C引入了高延迟,为a和B引入了相同的延迟。通过首先使用操作符,我取消了对C的订阅,而C没有时间执行,因此取消脚本会杀死C。有没有简单的方法让C继续在后台运行 @试验 公共无效测试_69_b引发异常{ List intList=Arrays.asListA,B,C; 打印开始; 可观察的测试=可观察的.fromintList .flatMapthis::FindRappers 第一 芬兰版画;

在解脚本后是否可以在rxJava中运行后台操作

例如:我创建了一个由3个字符串组成的流:a、B、C,我为C引入了高延迟,为a和B引入了相同的延迟。通过首先使用操作符,我取消了对C的订阅,而C没有时间执行,因此取消脚本会杀死C。有没有简单的方法让C继续在后台运行

@试验 公共无效测试_69_b引发异常{ List intList=Arrays.asListA,B,C; 打印开始; 可观察的测试=可观察的.fromintList .flatMapthis::FindRappers 第一 芬兰版画; test.subscribethis::printAtSub; 打印端; 睡眠时间:秒4; } 私有可观察FindRapperString id{ 返回Observable.justid.dounsubscribe->{ printWrapper已发布; } .observeOnSchedulers.io .flatmap->Observable.fromCallable->sendBackStringi; } 私有字符串sendBackStringString字符串{ 开关串{ 案例C: 睡眠时间为1000万; printHello+字符串; 返回字符串; 违约: 睡眠时间:百万分之十; printHello+字符串; 返回字符串; } }
如果您有一个要完成的长期运行的observate,那么最简单的方法就是引入share操作符。它将有两个订阅者,一个空的订阅者确保流程完成,另一个接受第一个项目并取消订阅

和往常一样,您需要关注对象的生命周期,并在资源不再可行时释放它们

// Hold on to long running subscriptions so we can release
// them at the proper time
CompositeSubscription longRunningSubscribers = new CompositeSubscription();
...
private Observable<String> findWrapperS(String id) {
    Observable<String> obs = Observable.just(id).doOnUnsubscribe(() -> {
        print("Wrapper <" + id + "> is released");
       })
      .observeOn(Schedulers.io())
      .flatMap(i -> Observable.fromCallable(() -> sendBackString(i)))
      .share();
      Subscription longTerm = obs
        .subscribe( ignored -> {}, error -> {} );
      longRunningSubscribers.add( longTerm );
      return obs;
}

现在,FindRappers返回一个可观察的,可以订阅和取消订阅,而无需停止长时间运行的操作。当操作终止时,将释放观察者链资源。但是,您可能仍需要致电longRunningSubscribers.unsubscribe以释放已订阅的资源。如果一切都完成了,那么它所做的就是释放少量内存,这不是一件坏事。

@BobDalgleish如果我在第一次之前尝试缓存会怎么样

@Test public void test_69_b() throws Exception {
    List<String> intList = Arrays.asList("A", "B", "C");
    print("start");
    Observable test = Observable.from(intList)
                                .flatMap(this::findWrapperS)
                                .cache();
                                .first();
    print("build finnished");
    test.subscribe(this::printAtSub);
    print("End");
    Sleeper.sleep(Duration.ofSeconds(4)); 
}

我觉得这有点类似于你的主张,即缓存为第二个订阅者保留发出的可观察序列。

必然地,观察者链需要有订阅者才能运行。您可以共享订阅,以便一个订阅方离开时不会终止观察者链。链完成后,所有剩余的订阅者都将离开,观察者链将释放其资源。@BobDalgleish请告诉我如何操作?谢谢,@BobDalgleish,它工作得很好,但我担心何时调用longRunningSubscribers.unsubscribe,因为在实际的用例中,sendBackStringi表示我不知道延迟时间的系统。从性能角度来看,让longRunningSubscribers不被取消订阅是否危险?让observer链被订阅是否危险。问题在于资源泄漏。如果观察者链正常或错误地完成,那么该链使用的资源将被释放。然而,订阅本身保留了一些小内存,这些内存最终应该被释放。如果我保留一个订阅的观察者链,操作员缓存也可能是解决方案。请参阅下面我的回答?您认为呢?通过使用缓存,您可以存储所有发出的值。我相信这是浪费,因为你永远不会使用它们。使用第二个订阅者可以更好地处理保持观察者链运行的副作用,也许可以添加ignoreElements以确保没有项目被保留。
@Test public void test_69_b() throws Exception {
    List<String> intList = Arrays.asList("A", "B", "C");
    print("start");
    Observable test = Observable.from(intList)
                                .flatMap(this::findWrapperS)
                                .cache();
                                .first();
    print("build finnished");
    test.subscribe(this::printAtSub);
    print("End");
    Sleeper.sleep(Duration.ofSeconds(4)); 
}