FromAsyncPattern 会处置不再使用的资源吗?

发布于 2024-12-04 19:31:15 字数 858 浏览 0 评论 0原文

FromAsyncPattern 会关闭我的网络响应吗:

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

如果我必须手动完成,还有比这更好的方法吗?

Will FromAsyncPattern close my 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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终遇你 2024-12-11 19:31:15

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

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));
                  });
反话 2024-12-11 19:31:15

作为 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 以使可观察在后台线程上执行 - 否则默认为 Scheduler.Immediate

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.

英雄似剑 2024-12-11 19:31:15

我不相信 FromAsyncPattern 可以关闭您的资源,即使它想这样做。它没有足够的信息来了解如何在其他地方使用进行异步调用的对象(本例中为 HttpWebRequest)或从异步调用返回的对象(本例中为 WebResponse)来了解何时将其保存到处置

也就是说,您仍然可以手动关闭资源,而无需额外的 DoSelect 调用。只需将第一个示例中的 Select 更改为:

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

据我所知,唯一会调用 Dispose 的 Rx 运算符是 Observable.Using。然而,根据它的签名,它如何或是否可以应用在这里并不是很明显,所以我采用了上述方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文