用Observable.Create包装Observable.FromEventPattern

时间:2018-10-26 16:50:20

标签: c# .net observable rx.net

两者之间的区别(取自RxCookbook on GitHub):

public static IObservable<TProperty> OnPropertyChanges<T, TProperty>(this T source, Expression<Func<T, TProperty>> property)
    where T : INotifyPropertyChanged
{
    return  Observable.Create<TProperty>(o=>
    {
        var propertyName = property.GetPropertyInfo().Name;
        var propertySelector = property.Compile();

        return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                        handler => handler.Invoke,
                        h => source.PropertyChanged += h,
                        h => source.PropertyChanged -= h)
                    .Where(e => e.EventArgs.PropertyName == propertyName)
                    .Select(e => propertySelector(source))
                    .Subscribe(o);
    });
}

这(由我自己写):

public static IObservable<TProperty> OnPropertyChanges<T, TProperty>(this T source, Expression<Func<T, TProperty>> property)
    where T : INotifyPropertyChanged
{
    var propertyName = property.GetPropertyInfo().Name;
    var propertySelector = property.Compile();

    return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                    handler => handler.Invoke,
                    h => source.PropertyChanged += h,
                    h => source.PropertyChanged -= h)
                .Where(e => e.EventArgs.PropertyName == propertyName)
                .Select(e => propertySelector(source));
}

我认为在第二个代码块中,propertyNamepropertySelector会在调用OnPropertyChanges时进行求值,而在第一个代码块中,每次有人订阅时都会对这些变量求值可观察的。但是,我无法弄清楚是否/为什么第一个块比第二个块更可取,以及为什么第一个块的作者决定使用Observable.Create

1 个答案:

答案 0 :(得分:0)

第一段代码作者的答案:

  

我对此的立场是,调用返回IObservable的方法应该什么都不做。对该返回值的订阅应调用任何副作用或处理。   如果需要在众多订阅之间分摊订阅成本,则应应用Rx中的各种多播选项。   在这种特定情况下,该论点是微弱的,但是随后使模式变得混乱,并为其他方法无需订阅即可“工作”打开了大门。我认为这是一个非常常见的错误,是造成竞争状况和资源泄漏的原因(请考虑打开连接,启动计时器等)