首页 > 解决方案 > 如何为 ios 实现 System.Reactive 调度程序

问题描述

我在我的 ios 项目中使用 System.Reactive 并且我知道我需要使用 ObserveOn 来指定在哪个线程上执行订阅者。但是我似乎无法正常工作。

就我所知,这应该可以工作,还是我执行错了?

public class UiContext : IScheduler
{
    /// <inheritdoc />
    public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
    {
        NSOperationQueue.MainQueue.AddOperation(() => action(this, state));
        return Disposable.Empty;
    }

    /// <inheritdoc />
    public IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
    {
        NSOperationQueue.MainQueue.AddOperation(() => action(this, state));
        return Disposable.Empty;
    }

    /// <inheritdoc />
    public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
    {
        NSOperationQueue.MainQueue.AddOperation(() => action(this, state));
        return Disposable.Empty;
    }

    /// <inheritdoc />
    public DateTimeOffset Now { get; }
}

    void SomeMethod()
    {
        WhenValidationChanged
            .ObserveOn(new UiContext())
            .SubscribeOn(new UiContext())
            .Throttle(TimeSpan.FromMilliseconds(50))
            .Subscribe(OnValidationChanged);
    }

    private void OnValidationChanged(object obj)
    {
        if (TableView.DataSource is InfoFieldsDataSource dataSource)
        {
            var validationErrors = dataSource.Items.OfType<InfoFieldViewModelBase>().Count(d => !d.IsValid);
            // Exception is raised about not being executed on UI thread
            _validationController.View.BackgroundColor = validationErrors > 0 ? UIColor.Green : UIColor.Red;
        }
    }

标签: xamarin.iossystem.reactive

解决方案


.ObserveOn(new UiContext())之前调用.Throttle(TimeSpan.FromMilliseconds(50))可能没有效果,因为Throttle可以更改调度程序 - 每个操作员都可以更改调度程序。您应该始终.ObserveOn在您希望将其应用于操作员或订阅呼叫之前执行此操作。


推荐阅读