Планирование в Rx .NET - PullRequest
       25

Планирование в Rx .NET

0 голосов
/ 24 сентября 2018

Ожидается, что все будет выполнено в главном потоке консольного приложения .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

Что я сделал не так?

1 Ответ

0 голосов
/ 24 сентября 2018

Scheduler.CurrentThread / CurrentThreadScheduler будет помещать в очередь элементы в том же потоке, который выполнял вызов расписания, который будет потоком, в котором таймер запускается.Вызов Scheduler.CurrentThread не связывает выполнение элементов, запланированных через него, с потоком, на который вы звоните Scheduler.CurrentThread, а с потоком, который вызывает .Schedule().

Также вы вызываете SubscribeOn()который влияет только на поток, где будет выполняться вызов .Subscribe().Если вы хотите контролировать выполнение обработки элемента, вы скорее хотите вызвать .ObserveOn().

Если вы хотите, чтобы все выполнялось в главном потоке, я предлагаю запустить таймер в главном потоке, указавпланировщик на наблюдаемом интервале:

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