我有一个wpf应用程序,它的所有viewModel都是从实现INotifyPropertyChanged的类NotifyPropertyChangeClass继承的(见下文)。
我想节流发送到视图的通知,以避免由于发送的通知太多而出现滞后。到目前为止,我实现的是使用反应扩展的方法样本来延迟每个属性。
问题是Gui被throttlingPeriod更新得很晚。在这段时期开始的时候,第一次举办这样的活动,会让人更有反应:

NotifyPropertyChangeClass的代码:
using System;
using System.ComponentModel;
using System.Reactive.Linq;
namespace MyNameSpace
{
public class NotifyPropertyChangeClass : INotifyPropertyChanged
{
public NotifyPropertyChangeClass(int throttlingPeriod)
{
var obs = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
h => this.privatePropertyChanged += h, h => this.privatePropertyChanged -= h);
var groupedByName = obs.Select(o => o.EventArgs.PropertyName).GroupBy(x => x).SelectMany(o => o.Sample(TimeSpan.FromMilliseconds(throttlingPeriod)));
groupedByName.Subscribe(o =>
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(o));
});
}
public event PropertyChangedEventHandler PropertyChanged;
private event PropertyChangedEventHandler privatePropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = privatePropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}我怎样才能实现我想要的?
发布于 2014-12-03 14:46:46
我没有试过,但你可以试试这个:
using System;
using System.ComponentModel;
using System.Reactive.Linq;
namespace MyNameSpace
{
public class NotifyPropertyChangeClass : INotifyPropertyChanged
{
private bool _isThrottling = false;
public NotifyPropertyChangeClass(int throttlingPeriod)
{
var obs = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
h => this.privatePropertyChanged += h, h => this.privatePropertyChanged -= h);
var groupedByName = obs.Select(o => o.EventArgs.PropertyName).GroupBy(x => x).SelectMany(o => o.Sample(TimeSpan.FromMilliseconds(throttlingPeriod)));
groupedByName.Subscribe(o =>
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(o));
_isThrottling = false;
});
}
public event PropertyChangedEventHandler PropertyChanged;
private event PropertyChangedEventHandler privatePropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
// Will fire the first time, the event is raised
if (!_isThrottling)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(o));
}
// Setting to true here will suppress raising the public event
// for every subsequent call, until the event is raised
// by the observable pattern and the flag is set to false again.
_isThrottling = true;
// Will always be raised
PropertyChangedEventHandler handler = privatePropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}发布于 2020-04-04 21:36:01
我还想在同时通知大量更改时(它正在拖住列表视图),我还想节流PropertyChanged通知程序。
最后,我使用了时间检查,因此如果一个新事件是在上次事件之后500 on通过之前引发的,它将在触发对所有属性的更新之前将此事件和任何进一步的事件阻塞500 on。代码如下
private DateTime _lastPropertyChange = DateTime.Now - TimeSpan.FromMinutes(1);
private readonly TimeSpan _propertyChangeBuffer = TimeSpan.FromMilliseconds(500);
private bool _propertyChangeBlock = false;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (_propertyChangeBlock)
return;
if (_lastPropertyChange < DateTime.Now - _propertyChangeBuffer)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
_lastPropertyChange = DateTime.Now;
}
else
{
_propertyChangeBlock = true;
ThreadPool.QueueUserWorkItem(p =>
{
Thread.Sleep(_propertyChangeBuffer);
_propertyChangeBlock = false;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
});
}
}https://stackoverflow.com/questions/27271089
复制相似问题