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

查看:14
本文介绍了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?

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

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?

推荐答案

简短回答:不,但你应该.StreamSubscriptionStreamSink 要求 关闭资源的契约中没有任何内容,但是如果不关闭某些用例可能会导致内存泄漏他们,即使在某些情况下,这样做可能会令人困惑.围绕这些类的部分困惑在于它们被重载,并且处理两个截然不同的用例:

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:

当你Stream,你会收到一个 StreamSubscription.通常,当您完成收听该 Stream 时,无论出于何种原因,您都应该关闭订阅.如果选择不这样做,并非所有流都会泄漏内存,但有些流会泄漏内存 - 例如,如果您从文件读取输入,不关闭流意味着文件句柄可能保持打开状态.

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.

所以,虽然不是严格要求,但我总是 cancel 完成访问流后.

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

StreamSink 最常见的实现是 StreamController,这是一个用于创建 Stream 的编程接口.通常,当您的流完成(即发出的所有数据)时,您应该关闭控制器.

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

在这种情况下,在读取最后一行时关闭controller 会很有意义.这会向用户发出一个信号(done 事件)文件已被读取,并且是有意义的(例如,您可以在那时关闭文件资源).

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.

希望这是有道理的并能帮助你!

Hope that makes sense and helps you out!

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

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