开发者

Will FromAsyncPattern dispose of resources no longer used?

开发者 https://www.devze.com 2023-04-05 13:30 出处:网络
Will FromAsyncPattern close my webresponse: var o = Observable.Return(HttpWebRequest.Create(\"http://foo.com\"))

Will FromAsyncPattern close my webresponse:

var o = Observable.Return(HttpWebRequest.Create("http://foo.com"))
                  开发者_如何学JAVA.SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
                      r.BeginGetResponse,
                      r.EndGetResponse)())
                  .Select(r => r.ContentLength);
// The response is now disposed

Or do I have to do it manually?

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);

If I have to do it manually, is there a better way than this?


Observable.Using can be used for this purpose as:

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));
                  });


As slightly cleaner version of the Using query would be this:

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;

I would suggest adding Scheduler.ThreadPool to at least the first Return to make the observable execute on a background thread - the default is Scheduler.Immediate otherwise.


I do not believe that FromAsyncPattern could close your resources, even if it wanted to. It does not have enough information about how either the object on which it is making the async calls (HttpWebRequest in this case) or the object returned from the async calls (WebResponse in this case) will be used elsewhere to know when it is save to Dispose.

That said, you can still close the resources manually without the extra Do and Select calls. Just change the Select in the first example to:

.Select(r => { using (r) { return r.ContentLength; }});

The only Rx operator that will call Dispose that I know of is Observable.Using. However, based on its signature, it was not immediately obvious how or if it could apply here, so I went with the above approach.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号