FromAsyncPattern会关闭我的webresponse:
var o = Observable.Return(HttpWebRequest.Create("http://foo.com"))
.SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
r.BeginGetResponse,
r.EndGetResponse)())
.Select(r => r.ContentLength);
// The response is now disposed
或者我必须手动完成吗?
var o = Observable.Return(HttpWebRequest.Create("http://foo.com"))
.SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
r.BeginGetResponse,
r.EndGetResponse)())
.Select(r => Tuple.Create(r, r.ContentLength))
.Do(t => t.Item1.Close())
.Select(t => t.Item2);
如果我必须手动完成,有没有比这更好的方法?
答案 0 :(得分:4)
Observable.Using
可用于此目的:
var o = Observable.Return(HttpWebRequest.Create("http://www.google.com"))
.SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
r.BeginGetResponse,
r.EndGetResponse)())
.SelectMany(r =>
{
return Observable.Using( () => r, (resp) => Observable.Return(resp.ContentLength));
});
答案 1 :(得分:1)
我不相信FromAsyncPattern
会关闭你的资源,即使它想要。它没有足够的信息来说明它进行异步调用的对象(在本例中为HttpWebRequest)或异步调用返回的对象(本例中为WebResponse)将如何在其他地方使用以了解它何时保存到Dispose
。
也就是说,您仍然可以手动关闭资源,而无需额外的Do
和Select
来电。只需将第一个示例中的Select
更改为:
.Select(r => { using (r) { return r.ContentLength; }});
我唯一会调用Dispose
的Rx运算符是Observable.Using
。但是,根据它的签名,它是如何或是否适用于此处并不是很明显,所以我采用了上述方法。
答案 2 :(得分:1)
Using
查询稍微清晰一点就是:
var o =
from rq in Observable.Return(HttpWebRequest.Create("http://foo.com"))
from cl in Observable.Using(() => rq.GetResponse(),
rp => Observable.Return(rp.ContentLength))
select cl;
我建议至少在第一个Scheduler.ThreadPool
添加Return
,以便在后台线程上执行observable - 否则默认为Scheduler.Immediate
。