我正在尝试使用Reactive Extensions来限制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的示例看起来非常简洁,但我无法将这些示例转换为我的解决方案。
为什么这会导致死锁,我该怎么做才能使其工作?
答案 0 :(得分: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();