J'ai certains appels qui doivent s'exécuter séquentiellement. Considérez un IService qui a une méthode Query et une méthode Load. La requête donne une liste de widgets, et la charge fournit un widget "par défaut". Par conséquent, mon service ressemble à ceci.Comment organiser ces appels à l'aide de Reactive Extensions (Rx) dans Silverlight?
void IService.Query(Action<IEnumerable<Widget>,Exception> callback);
void IService.Load(Action<Widget,Exception> callback);
Dans cet esprit, voici une esquisse du modèle de vue:
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);
}
}
}
Ce que je voudrais faire est de simplifier le flux de travail séquentiel d'appeler la requête et la valeur par défaut. Peut-être que la meilleure façon de le faire est imbriquée avec les expressions lambda comme je l'ai montré, mais j'ai pensé qu'il pourrait y avoir une manière plus élégante avec Rx. Je ne veux pas utiliser Rx dans l'intérêt de Rx, mais si cela peut me permettre d'organiser la logique ci-dessus pour qu'il soit plus facile à lire/maintenir dans la méthode, j'en profiterai. Idéalement, quelque chose comme:
Observable.Create(
()=>firstAction(),
()=>secondAction())
.Subscribe(action=>action(),error=>{ throw error; });
Avec la bibliothèque de threads de puissance, je ferais quelque chose comme:
Service.Query(list=>{result=list};
yield return 1;
ProcessList(result);
Service.Query(widget=>{defaultWidget=widget};
yield return 1;
CurrentWidget = defaultWidget;
qui le rend beaucoup plus évident que le flux de travail est séquentiel et élimine la nidification (les rendements sont partie de l'énumérateur asynchrone et sont des limites qui bloquent jusqu'à ce que les résultats reviennent).
Tout ce qui est similaire aurait du sens pour moi. Donc, l'essence de la question: est-ce que j'essaie d'insérer une cheville carrée dans un trou rond, ou y a-t-il un moyen de redéfinir les appels asynchrones imbriqués en utilisant Rx?
Je cherchais quelque chose de similaire à cette question: http://stackoverflow.com/questions/3280345/is-there-a -useful-design-pattern-pour-enchaîné-asynchrone-event-calls - si vous êtes capable de répondre à ma question avec votre expérience, cela serait apprécié =) –
Je travaille sur la preuve de concept pour montrer l'agrégation multiple (différents) appels de service et les exécuter séquentiellement. Vous permettra de savoir quand il sera prêt! –