我知道当我不想再接收任何活动时,我必须取消Stream
订阅。
即使在我收到“完成”后,我是否也必须这样做?事件?或者我是否会泄漏内存?
传递给另一个流的addStream
的Streams会发生什么?它们会自动取消吗?
StreamSink
方面关闭它们吗?
答案 0 :(得分:5)
简答:否。合同中的任何内容StreamSubscription
或StreamSink
都不需要关闭资源,在某些情况下,这样做可能会造成混淆。围绕这些类的部分混淆是它们被重载,并处理两个相当不同的用例:
让我们一次解决这些问题,首先,StreamSubscription
:
StreamSubscription
当您listen
到Stream
时,您会收到StreamSubscription
。通常,当您完成收听Stream
时,出于任何原因,您应该关闭订阅。如果不选择,并非所有流都会泄漏内存,但有些会 - 例如,如果您正在从文件读取输入,而不是关闭流意味着文件的句柄可能保持打开状态。
因此,虽然严格要求,但在访问流时,我总是 cancel
。
StreamSink
StreamSink
最常见的实现是StreamController
,它是创建Stream
的编程接口。通常,当您的流完成(即发出的所有数据)时,您应该关闭控制器。
这里有点令人困惑。让我们来看看这两种情况:
想象一下,您正在创建一个API,以逐行异步读取文件:
Stream<String> readLines(String path);
要实现此目的,您可以使用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
会很有意义。这向用户发出信号(完成事件),表明文件已被读取,并且有意义(例如,您可以在此时关闭文件资源)。
想象一下,您正在创建一个API来收听有关HackerNews的新闻文章:
Stream<String> readHackerNews();
这对关闭底层接收器/控制器没有多大意义。 HackerNews是否停止?像这样的事件流(或UI程序中的click
处理程序)传统上不会停止&#34;没有用户访问它(即取消StreamSubscription
)。
完成后你可以关闭控制器,但不是必需的。
希望有意义并帮助你!
答案 1 :(得分:2)
在我的案例中,我发现如果我有这样的代码:
Stream<String> readHackerNews(String path) {
StreamController<String> controller = StreamController<String>();
......
return controller.stream;
}
我看到警告消息“'dart.core.Sink'的关闭实例”。在Visual Studio代码中。 为了解决此警告,我添加了
controller.close()
有关OnCancel事件的事件处理程序,请参见下文:
Stream<String> readHackerNews(String path) {
StreamController<String> controller = StreamController<String>();
//TODO: your code here
controller.onCancel = () {
controller.close();
};
return controller.stream;
}
希望这会有所帮助!