预期所有操作都将在.NET Core 2.0控制台应用程序的主线程上执行,因此输出将被阻止10秒钟:

    static void Main(string[] args)
    {
        WriteLine($"We are on {Thread.CurrentThread.ManagedThreadId}");

        var subject = new Subject<long>();
        var subscription = subject.Subscribe(
            i => WriteLine($"tick on {Thread.CurrentThread.ManagedThreadId}"));

        var timer = Observable.Interval(TimeSpan.FromSeconds(1))
            .SubscribeOn(Scheduler.CurrentThread)
            .Subscribe(i => subject.OnNext(i));

        Thread.Sleep(10000);
    }


但是,情况并非如此–随机线程分派了新的一行来管理控制台:


We are on 1
tick on 4
tick on 5
tick on 4
tick on 4
tick on 4
tick on 4
tick on 4
tick on 4
tick on 5



我做错什么了?

最佳答案

Scheduler.CurrentThread / CurrentThreadScheduler将使项目在计划调度的同一线程中排队,这将是计时器恰好在其上运行的线程。调用Scheduler.CurrentThread不会将通过它计划的项目的执行固定在您调用Scheduler.CurrentThread的线程上,而是锁定在调用.Schedule()的线程上。

另外,您调用SubscribeOn()只会影响将要进行.Subscribe()调用的线程。如果要控制项目处理的执行,则希望调用.ObserveOn()

如果希望所有内容都在主线程上运行,建议通过在可观察的时间间隔上指定调度程序,在主线程上运行计时器:

Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.CurrentThread)

关于c# - Rx .NET中的计划,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52471403/

10-10 12:35