【问题标题】:RX PropertyChanged GroupBy deadlockRX PropertyChanged GroupBy 死锁
【发布时间】:2013-03-01 12:05:08
【问题描述】:

我正在尝试使用响应式扩展来限制 PropertyChanged 通知。有使用 GroupBy 执行此操作的示例,但为每个 PropertyName 创建一个订阅。

我想为所有属性处理 PropertyChanged 事件,并且我需要为每个 PropertyName 限制这些事件。

这是我目前所拥有的,但它会导致死锁。

ValuesPropertyChanged = Observable.FromEventPattern<PropertyChangedEventArgs>(value, "PropertyChanged")
    .GroupBy(o => o.EventArgs.PropertyName)
    .First()
    .Throttle(TimeSpan.FromSeconds(2))
    .Subscribe(args => HandlePropertyChanged(args.EventArgs.PropertyName));

死锁发生在对 .First() 的调用中。

如果我将该行更改为:

.Select(o => o.First())

我也试过了

.Select(o => o.FirstAsync())

GroupBy here 的示例看起来非常简洁,但我无法将这些示例转换为我的解决方案。

为什么这会导致死锁,我应该怎么做才能使它工作?

【问题讨论】:

    标签: system.reactive inotifypropertychanged


    【解决方案1】:

    认为这可能就是你所追求的:

    // assume MyObj : INotifyPropertyChanged, naturally
    var value = new MyObj();
    
    Action<string> HandlePropertyChanged = 
        name => Console.WriteLine("Got a change for name:" + name);
    
    // The query
    var valuesPropertyChanged = 
        // create from event stream
        from propChange in Observable.FromEventPattern<PropertyChangedEventArgs>(
                 value, 
                 "PropertyChanged")            
        // group events by property name
        group propChange by propChange.EventArgs.PropertyName into batchByName
        // Throttle the resulting batch
        from throttledByName in batchByName.Throttle(TimeSpan.FromSeconds(1))
        // then select each item of the "throttled output"
        select throttledByName;
    
    valuesPropertyChanged.Subscribe(args => 
        HandlePropertyChanged(args.EventArgs.PropertyName));
    
    for(int i=0;i<10;i++) 
    { 
        value.Value1 = i.ToString(); 
        value.Value2 = (i-1).ToString();
    }
    

    输出:

    Got a change for name:Value2
    Got a change for name:Value1
    

    这里是一样的,但有扩展方法:

    var valuesPropertyChanged =
        Observable.FromEventPattern<PropertyChangedEventArgs>(
                    _vm,
                    "PropertyChanged")
                    .GroupBy(propchange => propchange.EventArgs.PropertyName)
                    .Select(o => o.Throttle(TimeSpan.FromSeconds(1)))
                    .Merge();
    

    【讨论】:

    • 非常好,这确实可以满足我的要求,并且我已经成功地以扩展方法为例,使用它。谢谢
    • @TriggerPin 酷,没问题!在第一次设置 Rx 查询时,我总是发现“详细”语法非常方便......我以后总是可以优化/链接它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2014-06-08
    • 2013-11-30
    • 2013-12-25
    相关资源
    最近更新 更多