2017-01-22 4 views
1

Я хочу реализовать функцию автосохранения. У меня есть два Наблюдаемые:Автосохранение с RX в C#

  • IObservable<Unit> changes: излучает предмет каждый раз, когда пользователь редактирует текст
  • IObservable<Unit> saves: испускает сохранить событие каждый раз, когда кнопка сохранения нажата

Теперь я хочу, чтобы объединить те, кто в третий поток writeBack. Этот поток имеет подписчика, который записывает текущий текст в базу данных.

Как создать поток writeBack, чтобы он заполнил следующие свойства?

  • несохраненные изменения будут записаны назад, если там нету произошло какие-либо изменения в течение 3 секунд (как дроссельных)
  • ворота события записывает обратно в последнем НЕСОХРЕ сразу изменится

I хотите, чтобы только записывать несохраненные изменения. Я не хочу, чтобы сохранить текст, если:

  • есть сохранить событие, но никаких изменений
  • два сохранения событий в ряде, но никаких изменений в между
  • есть сохранить событие между изменением и его автосохранение

ответ

0

Это должно быть сделано. Сначала мы определяем раз мы хотим сохранить:

var saveTriggers = changes.Throttle(TimeSpan.FromSeconds(3)) 
    .Merge(saves); 

Далее процеживаем те, чтобы убедиться, что они соответствуют вашей логике: По крайней мере один редактировать между каждым сохранить и спасти не может прийти первой. SkipWhile здесь, чтобы убедиться, что Saves, предшествующий изменениям, игнорируется. Scan подсчитывает количество изменений между каждым сохранением. Нам остается только, когда это число переходит в 0 (это означает, что сработало сбой). И DistinctUntilChanged отфильтровывает последовательные сейвы.

var actualSaves = saveTriggers.Select(_ => EventType.SaveTrigger) 
    .Merge(changes.Select(_ => EventType.Edit)) 
    .SkipWhile(et => et == EventType.SaveTrigger) 
    .Scan(0, (editCount, eventType) => eventType == EventType.SaveTrigger ? 0 : editCount + 1) 
    .DistinctUntilChanged() 
    .Where(count => count == 0) 
    .Select(_ => Unit.Default); 

и используя класс перечислимой

enum EventType 
{ 
    SaveTrigger, 
    Edit 
} 
+0

Спасибо, это именно то, что он должен. Я нашел свое собственное решение, но он использовал Windows с задержкой потоков и был способ к сложным. Это намного проще. Хорошая идея использовать Scan. – Streamfighter

+0

Спасибо. В любое время, когда вы смотрите на логику с точки зрения истории, «Сканирование» должно быть первым, на что вы смотрите. – Shlomo

Смежные вопросы