Обертка Observable.FromEventPattern с Observable.Create - PullRequest
0 голосов
/ 26 октября 2018

Какая разница между этим (взято из RxCookbook на 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));
}

Я думаю, что во втором блоке кода propertyName и propertySelector будут оцениваться при вызове OnPropertyChanges, а в первом блоке эти переменные будут оцениваться каждый раз, когда кто-то подписывается на наблюдаемое. Однако я не могу понять, является ли / почему первый блок предпочтительнее второго, и почему автор первого блока решил использовать Observable.Create.

1 Ответ

0 голосов
/ 26 октября 2018

Ответ от автора первого блока кода:

Моя позиция заключается в том, что вызов метода, который возвращает IObservable, не должен ничего делать. Это подписка на это возвращаемое значение, которая должна вызывать любые побочные эффекты или обработку. Если стоимость подписки должна амортизироваться по многочисленным подпискам, то должны применяться различные параметры многоадресной рассылки в Rx. В этом конкретном случае аргумент слабый, однако он затем запутывает шаблон и открывает двери для других методов, чтобы «сделать работу» без подписки. Я вижу это как очень распространенную ошибку и источник условий гонки и утечки ресурсов (подумайте об открытии соединения, запуске таймера и т. Д.)

...