Dart:我必须取消Stream订阅并关闭StreamSinks吗? [英] Dart: Do I have to cancel Stream subscriptions and close StreamSinks?

查看:398
本文介绍了Dart:我必须取消Stream订阅并关闭StreamSinks吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我不想再接收任何事件时,必须取消 Stream 订阅。
即使收到完成事件后我也必须这样做吗?还是我会发生内存泄漏?

I know I have to cancel Stream Subscriptions when I no longer want to receive any events. Do I have to this even after I receive a 'Done' event? Or do I get memory leaks?

传递给另一个Stream的 addStream 的Stream会发生什么情况?他们会自动取消吗?

What happens to Streams that are passed to addStream of another Stream? Are they automatically canceled?

StreamSink 端相同的问题如果流已经完成,我是否必须关闭它们?

Same Question on the StreamSink side do I have to close them if the stream is already done?

推荐答案

简短回答:否,但您应该 StreamSubscription StreamSink 不需要的合同中没有任何内容,但有些用途如果不关闭它们,可能会导致内存泄漏,即使在某些情况下,这样做可能会造成混淆。这些类的部分困惑在于它们被重载,并且处理两个相当不同的用例:

Short-answer: no, but you should. Nothing in the contract of either StreamSubscription or StreamSink requires closing the resources, but some use cases can lead to memory leaks if you don't close them, even though in some cases, doing so might be confusing. Part of the confusion around these classes is that they are overloaded, and handle two fairly distinct use cases:


  1. 资源流(例如文件I / O,网络访问)

  2. 事件流(如点击处理程序)

让我们解决这些问题一次,一次, StreamSubscription

Let's tackle these subjects one at a time, first, StreamSubscription:

当您 ,您会收到 StreamSubscription 。通常,当您完成收听该时,无论出于何种原因,都应关闭订阅。并非所有流都将泄漏内存(如果选择不泄漏),但是有些流泄漏-例如,如果您正在从文件中读取输入,则不关闭流将意味着该文件的句柄可能保持打开状态。

When you listen to a Stream, you receive a StreamSubscription. In general, when you are done listening to that Stream, for any reason, you should close the subscription. Not all streams will leak memory if choose not to, but, some will - for example, if you are reading input from a file, not closing the stream means the handle to the file may remain open.

因此,尽管不是严格要求,但我会始终 取消 完成访问流后。

So, while not strictly required, I'd always cancel when done accessing the stream.

StreamSink的最常见实现 StreamController ,这是创建 Stream 的程序接口。通常,当您的流是 complete (即发出的所有数据)时,您应该关闭控制器。

The most common implementation of StreamSink is StreamController, which is a programmatic interface to creating a Stream. In general, when your stream is complete (i.e. all data emitted), you should close the controller.

在这里它有点令人困惑。让我们看一下这两种情况:

Here is where it gets a little confusing. Let's look at those two cases:

假设您正在创建一个API以异步读取一个文件逐行显示:

Imagine you were creating an API to asynchronously read a File line-by-line:

Stream<String> readLines(String path);

要实现此目的,您可以使用 StreamController

To implement this, you might use a StreamController:

Stream<String> readLines(String path) {
  SomeFileResource someResource;
  StreamController<String> controller;
  controller = new StreamController<String>(
    onListen: () {
      someResource = new SomeFileResource(path);
      // TODO: Implement adding to the controller.
    },
  );
  return controller.stream;
}

在这种情况下,关闭 控制器读完最后一行时。这会向用户发出信号( done 事件),表明该文件已被读取并且是有意义的(例如,您可以在此时关闭File资源)。

In this case, it would make lots of sense to close the controller when the last line has been read. This gives a signal to the user (a done event) that the file has been read, and is meaningful (you can close the File resource at that time, for example).

假设您正在创建一个API,以收听HackerNews上的新闻文章:

Imagine you were creating an API to listen to news articles on HackerNews:

Stream<String> readHackerNews();

此处关闭底层接收器/控制器的意义不大。 HackerNews是否会停止?像这样的事件流(或UI程序中的 click 处理程序)在没有用户访问的情况下通常不会停止(即取消 StreamSubscription )。

Here it makes less sense to close the underlying sink/controller. Does HackerNews ever stop? Event streams like this (or click handlers in UI programs) don't traditionally "stop" without the user accessing for it (i.e cancelling the StreamSubscription).

完成操作后,您可以关闭控制器,但这不是必需的。

You could close the controller when you are done, but it's not required.

希望有帮助并帮助您!

这篇关于Dart:我必须取消Stream订阅并关闭StreamSinks吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆