C# 我可以简化使用Observable.Create从json请求返回对象的过程吗

C# 我可以简化使用Observable.Create从json请求返回对象的过程吗,c#,system.reactive,C#,System.reactive,我一直在做这样的web请求: public IObservable<Foo> GetFoo(string fooId) { var uri = /* set up the GET query parameters here */; return Observable.Create<Foo>( obs => new HttpClient().GetAsync(uri) .ToObservable()

我一直在做这样的web请求:

public IObservable<Foo> GetFoo(string fooId)
{
    var uri = /* set up the GET query parameters here */;

    return Observable.Create<Foo>(
        obs => new HttpClient().GetAsync(uri)
            .ToObservable()
            .Subscribe(response =>
            {
                try
                {
                    response.EnsureSuccessStatusCode();

                    response.Content.ReadAsStringAsync()
                        .ToObservable()
                        .Select(JObject.Parse)
                        .Select(json => new Foo(json))
                        .Subscribe(foo =>
                        {
                            obs.OnNext(foo);
                            obs.OnCompleted();
                        });
                }
                catch (Exception e)
                {
                    obs.OnError(e);
                }
            }));
public IObservable GetFoo(字符串fooId)
{
var uri=/*在此处设置GET查询参数*/;
返回可观察的。创建(
obs=>new HttpClient().GetAsync(uri)
.TooObservable()文件
.订阅(响应=>
{
尝试
{
response.EnsureSuccessStatusCode();
response.Content.ReadAsStringAsync()
.TooObservable()文件
.Select(JObject.Parse)
.Select(json=>newfoo(json))
.订阅(foo=>
{
obs.OnNext(foo);
obs.OnCompleted();
});
}
捕获(例外e)
{
obs.OnError(e);
}
}));
}

然而,我觉得作为Rx的新手,我可能缺少一些简化我所写内容的方法。看起来外部的可观察的只是内部的一个包装,我可以(以某种方式)将其公开——我只是不知道如何公开。

试试看:

return Observable.Defer(() => HttpClient().GetAsync(uri))
    .SelectMany(async x => { x.EnsureSuccessStatusCode(); return x.Content.ReadAsStringAsync(); })
    .Select(JObject.Parse)
    .Select(json => new Foo(json));
这里的
Observable.Defer
使其与原始方法wrt订阅的语义相匹配(即,您订阅两次,您发出两个HTTP请求)。

尝试一下:

return Observable.Defer(() => HttpClient().GetAsync(uri))
    .SelectMany(async x => { x.EnsureSuccessStatusCode(); return x.Content.ReadAsStringAsync(); })
    .Select(JObject.Parse)
    .Select(json => new Foo(json));

这里的
Observable.Defer
使其与原始方法wrt订阅的语义相匹配(即,您订阅两次,您发出两个HTTP请求)。

Observable。使用
将使其完美。@CoryNelson,使用
如何改进这一点?我更喜欢
可观察。从异步
可观察。延迟
-没有功能上的区别,但它使代码对我来说更易读。它确实有用于将订阅处理映射到取消令牌的重载,但您也可以在
Observable上找到它们。DeferAsync
@JamesWorld谢谢,我同意
fromsync
更具可读性。它还删除了关于等待被忽略的警告。不过,我修复了警告,但FromAsync也很有效:)
可观察。使用
将使这一点变得完美。@CoryNelson,使用
如何改进这一点?我更喜欢
可观察。从异步
可观察。延迟
-没有功能上的区别,但它使代码对我来说更易读。它确实有用于将订阅处理映射到取消令牌的重载,但您也可以在
Observable上找到它们。DeferAsync
@JamesWorld谢谢,我同意
fromsync
更具可读性。它还删除了关于等待被忽略的警告。hwhoops,我修复了该警告,但是fromsync也很有效:)