我有一些必须按顺序执行的调用。考虑一个包含查询和加载方法的 IService 接口。查询提供了一个小部件列表,而加载提供了一个“默认”小部件。因此,我的服务看起来像这样。
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);
}
}
}
我希望能够简化调用查询和默认操作的顺序工作流程。也许最好的方法是使用像我展示的嵌套lambda表达式,但我想可能有一种更优雅的方式使用Rx。我不想仅仅为了使用Rx而使用Rx,但如果它可以让我更轻松地阅读/维护该方法中的逻辑,我会利用它。理想情况下,类似于:
Observable.Create(
()=>firstAction(),
()=>secondAction())
.Subscribe(action=>action(),error=>{ throw error; });
使用强大的线程库,我会这样做:
Service.Query(list=>{result=list};
yield return 1;
ProcessList(result);
Service.Query(widget=>{defaultWidget=widget};
yield return 1;
CurrentWidget = defaultWidget;
这使得工作流程更加明显,并消除了嵌套(yield是异步枚举器的一部分,是阻止结果返回的边界)。
任何类似的方法对我来说都是有意义的。
所以问题的实质是:我是在试图把方形钉子塞进圆孔中,还是有一种使用Rx重新定义嵌套异步调用的方法?