Tengo algunas llamadas que se deben ejecutar secuencialmente. Considere un IService que tiene un método Query y un Load. La consulta proporciona una lista de widgets y la carga proporciona un widget "predeterminado". Por lo tanto, mi servicio se ve así.¿Cómo organizaría estas llamadas usando Reactive Extensions (Rx) en Silverlight?
void IService.Query(Action<IEnumerable<Widget>,Exception> callback);
void IService.Load(Action<Widget,Exception> callback);
Con esto en mente, aquí es un esbozo del modelo de vista:
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);
}
}
}
Lo que me gustaría hacer es simplificar el flujo de trabajo secuencial de llamar a consulta y el valor por defecto. Tal vez la mejor manera de hacerlo es anidando con expresiones lambda como he mostrado, pero pensé que podría haber una manera más elegante con Rx. No quiero usar Rx por Rx, pero si me permite organizar la lógica anterior para que sea más fácil de leer/mantener en el método, lo aprovecharé. Idealmente, algo así como:
Observable.Create(
()=>firstAction(),
()=>secondAction())
.Subscribe(action=>action(),error=>{ throw error; });
Con la librería de hilos de potencia, que haría algo como:
Service.Query(list=>{result=list};
yield return 1;
ProcessList(result);
Service.Query(widget=>{defaultWidget=widget};
yield return 1;
CurrentWidget = defaultWidget;
Eso hace que sea mucho más evidente que el flujo de trabajo es secuencial y elimina anidación (los rendimientos son parte del enumerador asincrónico y son los límites que bloquean hasta que los resultados vuelven).
Cualquier cosa similar tendría sentido para mí.
Entonces, la esencia de la pregunta: ¿estoy tratando de encajar una clavija cuadrada en un agujero redondo, o hay alguna manera de redefinir las llamadas asíncronas anidadas usando Rx?
que estaba buscando algo similar para esta pregunta: http://stackoverflow.com/questions/3280345/is-there-a -useful-design-pattern-for-chained-asynchronous-event-calls - si eres capaz de responder mi pregunta con tu experiencia, sería apreciada =) –
Estoy trabajando en la prueba del concepto para mostrar múltiples agregados (diferentes) llamadas de servicio y ejecutándolas secuencialmente. ¡Te avisaremos cuando esté listo! –