反应性扩展.NetCore在MainThread上观察

时间:2018-06-25 11:44:44

标签: linux .net-core system.reactive

我正在尝试并行执行很多网络操作,并且我想为每个操作设置一个超时时间。

由于Parallel.ForEach没有简单的超时选项,因此我正在使用System.Reactive。

这是我的代码:

public void networkOps(List<MacCpe> source, Action<List<Router>, List<Exception>> onDone) {

var routers = new List<Router>();
var exceptions = new List<Exception>();

Observable.Defer(() => source.ToObservable()) 
    .ObserveOn(Scheduler.CurrentThread)
            .SubscribeOn(Scheduler.Default)
            .SelectMany(it => 
                Observable.Amb(
                            Observable.Start(() => {
                                switch(it.type) {
                                    case AntennaType.type1: {
                                        //network stuff
                                    }
                                    break;

                                    case AntennaType.type2: {
                                       //network stuff
                                    }
                                    break;

                                    case AntennaType.type3: {
                                       //network stuff
                                    }
                                    break;

                                    case AntennaType.type4: {
                                      //network stuff
                                    }
                                    break;

                                    default: throw new NullReferenceException("Nothing");
                                }
                            }).Select(_ => true),
                            Observable.Timer(TimeSpan.FromSeconds(60)).Select(_ => false)
                        ),
                        (it, result) => new { it, result }
                    )
                    .Subscribe (
                        x => {
                            Console.WriteLine("checked item number " + x.it.Id);
                        },
                        ex => {
                            Console.WriteLine("error string");
                        }, () => {
                            onDone(routers, exceptions);
                        }
                    );
}

我正在使用Observable.Amb运算符并行运行一个60秒的计时器,该计时器可以超时。

但是,当我运行此方法时,程序将立即退出,而无需进入onDone回调。

我在线看到可以在线程池上运行阻塞代码的同时使用ObserveOnDispatcher在Ui线程上进行观察,但是我正在终端应用程序服务器端的Linux上的dotnet核心上使用它。

在控制台应用程序中如何观察“主线程”?

预先感谢您的答复。

1 个答案:

答案 0 :(得分:2)

在替换Parallel.ForEach时,听起来好像很高兴进行屏蔽操作。使用Rx进行设置的方式不是阻塞操作,因此该方法立即结束。

修复非常简单。只需将您的.Subscribe更改为此:

.Do(
    x =>
    {
        Console.WriteLine("checked item number " + x.it.Id);
    },
    ex =>
    {
        Console.WriteLine("error string");
    }, () =>
    {
        onDone(routers, exceptions);
    }
)
.Wait();

在确定您需要.ObserveOn(Scheduler.CurrentThread).SubscribeOn(Scheduler.Default)之前,我也会摆脱它们。