0

Reactive Extensionsを使用して、PropertyChanged通知を抑制しようとしています。GroupByを使用してこれを行う例がありますが、PropertyNameごとに1つのサブスクリプションが作成されます。

すべてのプロパティの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の例はかなり簡潔に見えますが、これらの例を自分のソリューションに変換することに頭を悩ませることはできません。

なぜこれがデッドロックを引き起こすのですか、そしてこれを機能させるにはどうすればよいですか?

4

1 に答える 1

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();
于 2013-03-01T17:25:50.153 に答える