繁体   English   中英

如何循环 Observable Rx 直到满足条件?

[英]How to loop Observable Rx until condition met?

我发现这个很好的答案与我要解决的问题非常相似:

等待退出时进程有时会挂起

我第一次使用这个 System.Reactive package 虽然所以我在使用和语法上苦苦挣扎。 我正在尝试修改此块以满足我的需要:

     var processExited =
            // Observable will tick when the process has gracefully exited.
            Observable.FromEventPattern<EventArgs>(process, nameof(Process.Exited))
                // First two lines to tick true when the process has gracefully exited and false when it has timed out.
                .Select(_ => true)
                .Timeout(TimeSpan.FromMilliseconds(processTimeOutMilliseconds), Observable.Return(false))
                // Force termination when the process timed out
                .Do(exitedSuccessfully => { if (!exitedSuccessfully) { try { process.Kill(); } catch {} } } );

我希望它在超时时检查 stdOut 缓冲区中的特定字符串,如果找到它则退出,否则继续直到下一次超时。 而且,我只想在我“放弃”并终止进程之前做这么多超时,所以在循环中,如果它不退出,我会增加一个计数器并检查它。 感谢您的帮助

添加说明,我想要这样的东西:

int timeoutCount = 0;
const int maxTimeoutCount =5;

然后在 observable 中,类似.Do(exitedSuccessfully => {

          if (!exitedSuccessfully) {
                        try {
                            if (timeoutCount >= maxTimeOutCount || output.ToString().Contains("string_i-m_looking_for_in_output_to_trigger_exit")) {
                                process.Kill();
                            }
                            timeOutCount++;
                        }
                        catch { }
                    }

反应式的基本设计理念是避免外部 state - 并以声明方式表达行为。 在 Rx 中,您可能需要 model 传统上以不同方式变异 state。

将进程作为可观察对象的惯用方法是将进程的生命周期链接到对可观察对象的订阅。 订阅启动进程,取消订阅停止进程,反之亦然,正常退出的进程完成了 observable。

我已经在Github 上实现了这个 model 它是 C# 和 F# 的单个文件库,它将进程的标准输入/输出抽象为可观察的。

使用 model:

 StdioObservable
    .Create("process.exe")
    .TakeUntil(line => line.Contains("Done")) // unsub when you match
    .Timeout(TimeSpan.FromSeconds(30)) // no output for 30 seconds
    .Catch((Exception exn) => Observable.Empty<string>()) //handle timeout or other
    .Subscribe();

如果您想在一段时间内终止该进程,尽管它会产生一些 output,请改用 .Take .Take(TimeSpan.FromSeconds(30))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM