При работе с Rx необходимо учитывать двойственность между IEnumerable<T>
& IObservable<T>
(а также IEnumerator<T>
& IObserver<T>
).
Вы всегда должны искать объекты, которые реализуютIEnumerable<T>
и подумайте, как бы вы заменили их на IObservable<T>
.
. В своем вопросе вы говорите, что у вас есть таймер, добавляющий некоторые цифры к List<int>
, который вы хотите наблюдать, и добавляете новые числасписок.Поэтому я хотел бы рассмотреть вопрос о замене списка на IObservable<int>
.Хитрость здесь не в том, чтобы посмотреть список (или ObservableCollection<int>
), а в том, чтобы использовать Rx в качестве основной части вашего кода.
Итак, вот простой пример.
Начните с основных элементов, описанных в вашем вопросе:
var dispatchTimer = new DispatcherTimer();
var random = new Random();
var listBox = new ListBox();
Создайте наблюдаемую из dispatchTimer
:
IObservable<IEvent<EventArgs>> ticks =
Observable.FromEvent(
h => dispatchTimer.Tick += h,
h => dispatchTimer.Tick -= h);
Запросите наблюдаемую для создания новой наблюдаемой случайных чисел:
IObservable<int> randomNumbers =
from tick in ticks
select random.Next(1, 11);
Теперь подпишитесь на случайные числа, наблюдаемые для обновления поля списка:
_updateListBoxSubscription =
randomNumbers.ObserveOnDispatcher().Subscribe(n => listBox.Items.Add(n));
Вызов .ObserveOnDispatcher()
обеспечит добавление номеров в поле списка наПоток пользовательского интерфейса.
Вам необходимо определить поле или свойство для хранения ссылки на подписку, чтобы она не собирала мусор.Это именно то, что поля обработчика событий делают, когда вы добавляете обработчик, но с Rx вы должны явно сделать это.
private IDisposable _updateListBoxSubscription;
Итак, у вас теперь есть список, обновляемый из случайных чисел, сгенерированных винтервал, указанный во времени.
Это так просто.Надеюсь, это поможет.