Observable中的通知并行性

时间:2017-05-02 18:38:32

标签: c# multithreading system.reactive

我有以下可观察的

IObservable<Work> observable = SomeMethodToGetWorkToDo();

每次在上面调用OnNext时,我都需要在一个单独的线程中完成工作。每项工作都需要很长时间才能完成,所以我不能让队列中的其他Work项等待,只要有足够的系统资源。

我认为ObserveOn可以解决我的问题,但是当我运行一些Console.WriteLine调用来查看线程ID时,我看到每个通知调用都有相同的线程ID。

如何确保OnNext中的并行性?

2 个答案:

答案 0 :(得分:5)

您需要将“要做的工作”转换为一系列“工作正在完成”的令牌,然后再收集这些令牌。最简单的方法是使用TPL作为任务执行工作(最终将在线程池上运行任务)。像这样:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.gin.ordering, PID: 22005
              java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RadioGroup.clearCheck()' on a null object reference
                  at com.example.gin.ordering.alcoholType$1.onItemClick(alcoholType.java:90)
                  at android.widget.AdapterView.performItemClick(AdapterView.java:339)
                  at android.widget.AbsListView.performItemClick(AbsListView.java:1549)
                  at android.widget.AbsListView$PerformClick.run(AbsListView.java:3723)
                  at android.widget.AbsListView$3.run(AbsListView.java:5707)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:145)
                  at android.app.ActivityThread.main(ActivityThread.java:6918)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

答案 1 :(得分:3)

ObserveOn效果如下:

var sample = Observable.Interval(TimeSpan.FromMilliseconds(100));

sample
    .SelectMany(l => Observable.Return(l)
        .ObserveOn(TaskPoolScheduler.Default /*or NewThreadScheduler.Default */)
    )
    .Select(l => Thread.CurrentThread.ManagedThreadId)
    .Take(9)
    .Subscribe(i => Console.WriteLine(i));

诀窍是在不同的线程上处理不同的项目,它们必须位于不同的流上。