У меня есть несколько вызовов, которые должны выполняться последовательно. Рассмотрим IService, у которого есть Query и метод Load. Запрос предоставляет список виджетов, а загрузка предоставляет виджет «по умолчанию». Следовательно, мой сервис выглядит следующим образом.
void IService.Query(Action<IEnumerable<Widget>,Exception> callback);
void IService.Load(Action<Widget,Exception> callback);
Имея это в виду, вот примерный эскиз модели вида:
public class ViewModel : BaseViewModel
{
public ViewModel()
{
Widgets = new ObservableCollection<Widget>();
WidgetService.Query((widgets,exception) =>
{
if (exception != null)
{
throw exception;
}
Widgets.Clear();
foreach(var widget in widgets)
{
Widgets.Add(widget);
}
WidgetService.Load((defaultWidget,ex) =>
{
if (ex != null)
{
throw ex;
}
if (defaultWidget != null)
{
CurrentWidget = defaultWidget;
}
}
});
}
public IService WidgetService { get; set; } // assume this is wired up
public ObservableCollection<Widget> Widgets { get; private set; }
private Widget _currentWidget;
public Widget CurrentWidget
{
get { return _currentWidget; }
set
{
_currentWidget = value;
RaisePropertyChanged(()=>CurrentWidget);
}
}
}
То, что я хотел бы сделать, это упростить последовательный рабочий процесс вызова запроса, а затем по умолчанию. Возможно, лучший способ сделать это - использовать лямбда-выражения, как я показал, но я подумал, что может быть более элегантный способ с Rx. Я не хочу использовать Rx ради Rx, но если это позволит мне организовать вышеописанную логику, чтобы ее было легче читать / поддерживать в методе, я воспользуюсь этим. В идеале что-то вроде:
Observable.Create(
()=>firstAction(),
()=>secondAction())
.Subscribe(action=>action(),error=>{ throw error; });
С библиотекой Power Threading я бы сделал что-то вроде:
Service.Query(list=>{result=list};
yield return 1;
ProcessList(result);
Service.Query(widget=>{defaultWidget=widget};
yield return 1;
CurrentWidget = defaultWidget;
Это делает гораздо более очевидным, что рабочий процесс является последовательным и исключает вложение (выходы являются частью асинхронного перечислителя и являются границами, которые блокируют, пока результаты не вернутся).
Что-нибудь подобное имело бы смысл для меня.
Итак, суть вопроса: пытаюсь ли я вставить квадратный колышек в круглое отверстие или есть способ переопределить вложенные асинхронные вызовы с помощью Rx?