ReactiveExtension按需调用异步代码

时间:2015-09-04 11:24:42

标签: c# .net system.reactive

我有一个属性IObservable<ServiceStatus>,应该使用使用异步模式的方法按需更新。如果发生任何错误,应该吞下它。 statusNeedToBeUpdated是一个可观察的信息,当我的财产应该更新时通知我。基本上,以下代码可以完成需要完成的任务:

Status = statusNeedToBeUpdated
    .Select(_ => {
        try {
            var task = client.ServiceStatus.GetAsync();
            task.Wait();
            return task.Result;
        }
        catch (Exception) {
            return null;
        }
    })
    .Where(status => status != null);

我认为应该有更高级的方法来处理对client.ServiceStatus的异步调用:我想出了这个:

Status = statusNeedToBeUpdated
    .Select(async _ => await client.ServiceStatus.GetAsync())
    .Catch(Observable.Return(Task.Factory.StartNew(()=> (ServiceStatus)null)))
    .Where(task => task.Result != null)
    .Select(task => task.Result);

这个解决方案更好,但我不喜欢启动一个只返回null的新任务。 有没有人知道更好的解决方案。

2 个答案:

答案 0 :(得分:2)

您可以使用Observable.FromAsync来返回已完成的任务,而不是创建新任务。

但您也可以使用Status = statusNeedToBeUpdated .Select(_ => Observable.FromAsync<ServiceStatus>(async () => await client.ServiceStatus.GetAsync()) .SelectMany(s=> s); 来简化它。

var port = normalizePort(process.env.PORT || '9999');
app.set('port', port);

答案 1 :(得分:1)

在我看来,你需要这个查询:

Status =
    statusNeedToBeUpdated
        .SelectMany(_ =>
            Observable
                .FromAsync(() => client.ServiceStatus.GetAsync())
                .Retry());

这将在任何时候重试GetAsync抛出错误并避免返回虚拟值或任务。