Я попробовал код и добавил новый элемент каждые 100 мс, и был ... озадачен, мягко говоря, пока не случайно завис над Throttle
и не увидел:
Игнорирует элементы из наблюдаемой последовательности, за которой следует другой элемент в течение определенного относительного времени.
Я подозреваю, что, как и я, вы ожидали, что Throttle()
вернет последний элемент в окне. Хотя его описание в ReactiveX.io равно
испускает предмет из Обсерватории, только если прошло определенное время без его испускания другого предмета
А в документации говорится:
Для потоков, которые никогда не имеют промежутков, больших или равных dueTime между элементами, результирующий поток не будет создавать никаких элементов.
На самом деле, я использовал его таким образом в прошлом, но каким-то образом я каждый раз переключаюсь по названию, пока не вспомню, что фактическая операция отбрасывает , а не регулирует.
Когда я замедлял таймер, например, каждые 300 мс, я начинал получать результаты.
Оператор, который возвращает последнее событие в окне: Sample , а не Throttle. Если это то, что вы хотите, вы должны использовать
.Sample( TimeSpan.FromMilliseconds(300))
вместо Throttle
.
Используйте Throttle
, если вы хотите обновить пользовательский интерфейс только после , когда уведомления перестают поступать в течение 250 мс
Обновление
Чтобы проверить это поведение, я создал консольное приложение. Я добавил несколько исправлений в код вопроса, чтобы он мог скомпилироваться:
public class ClassWrapper : BaseClassWrapper
{
public string SomeProperty { get; set; }
public ClassWrapper()
{
Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
(x => ClassDTO.MyCollection.CollectionChanged += x, x => ClassDTO.MyCollection.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add ||
x.EventArgs.Action == NotifyCollectionChangedAction.Replace ||
x.EventArgs.Action == NotifyCollectionChangedAction.Remove)
.Throttle( TimeSpan.FromMilliseconds(250))
.Subscribe(x =>
{
RaisePropertyChanged( ()=> SomeProperty);
});
}
}
Метод приложения Main
добавляет элемент каждые 100 мс. Через 250 мс после добавления последнего элемента генерируется одно событие уведомления и печатается сообщение:
static async Task Main(string[] args)
{
Console.WriteLine("Started");
var c = new ClassWrapper();
c.PropertyChanged += (sender, e) =>
{
Console.WriteLine($"Collection has {c.ClassDTO.MyCollection.Count} items");
};
for (int i = 0; i < 100; i++)
{
c.ClassDTO.MyCollection.Add(new OtherClass());
await Task.Delay(100);
}
Console.ReadKey();
}