Всегда начинайте с разбивки проблемы на то, что у вас есть и что вы хотите, превратите это в сигнатуру функции и посмотрите, обнаружит ли это реализацию.
выполнить действие из-за задержкисобытие, которое отменяется другим событием
, поэтому у вас есть источник запуска, длительность задержки и источник отмены
Желаемое поведение, которое вы описываете:
- Для каждого источника триггера
- Задержка на указанное время
- Если в течение этого времени отмена не происходит, выведите исходное значение
Теперь, когда у нас естьНапример, мы можем сделать подпись и рассмотреть реализацию
??? DelayOrCancel<???>(this IObservable<T> source,
TimeSpan delay,
IObservable<TCancel> cancel);
В зависимости от природы источника отмены, вам может понадобиться передать Func<T, IObservable<TCancel>>
, но, похоже, это будет работать в вашем случае.
Первые две строки спецификации предполагают SelectMany
(каждый элемент в источнике делает другую наблюдаемую, которая будет объединена обратно в одну наблюдаемую).Чтобы получить отмену, нам просто нужно дождаться задержки или до отмены, что мы можем сделать с TakeUntil
.Поскольку конечными элементами будут исходные элементы, тип возврата будет таким же, как и исходный.
IObservable<T> DelayOrCancel<T, TCancel>(this IObservable<T> source,
TimeSpan delay,
IObservable<TCancel> cancel)
{
//argument checking skipped
return from s in source
from i in Observable.Timer(delay).TakeUntil(cancel)
select s;
}