Kernel James
Kernel James

Reputation: 4064

Is it required to call streamSubscription.cancel() to free resources in Flutter?

In Flutter, if I obtained a StreamSubscription from a Stream, what is the proper etiquette to clean up resources when I am done?

  1. Stream doesn't have a cancel method so I can't clean up that.
  2. StreamSubscription has a cancel method but does calling cancel here also cancel the corresponding Stream too?
  3. If the Stream closes by itself when it is done, will it automatically signal to SteamSubscription to cancel automatically, meaning I don't need to manually close it? Otherwise it will hold a list of listeners somewhere and prevent garbage collection.

I can imagine 2 hypothetical scenarios:

  1. A Stream implementation that just returns a never ending list of increasing even numbers. Ideally, Stream should never cancel itself and shouldn't generate output unless there is an active subscription too. This meaning canceling a subscription should be enough to free all resources and prevent Stream from running further.

  2. A Stream implementation that listens for clicks on a button. Ideally, the Stream should offer a cancel method when the user is no longer interested in listening to clicks. If the user calls cancel on the StreamSubscription only, will this also cancel the Stream? If somewhere upstream there is code that canceled the Stream such as the button being garbage collected, is the StreamSubscription automatically canceled and all references cleared?

Upvotes: 1

Views: 1070

Answers (1)

Mohamed Alsaid
Mohamed Alsaid

Reputation: 960

  1. Stream has two types, "Single-subscription" streams and "broadcast" streams [1]. single subscription uses async* which generates the stream within a method body, this is a cold stream that only works when it is subscribed to and it ends the stream when the method body is exited or when the single subscriber cancels. On the other hand, broadcast streams are hot streams that have a StreamController that can be used to emit to the Stream or cancel it but you would need to have access to the parts that generate that Stream.

  2. Canceling the subscription will cancel cold streams since they have only one subscriber. Made an example for it here. And for broadcast/hot streams, you have full control with a StreamController, so you can cancel the stream or not, but it's recommended to do so when the last subscriber un-subscribes [2].

  3. When a Stream closes, it un-subscribes all listeners and then inform them of the event [1], you can pass a function to onDone when listening to a Stream to receive this event.

As for the titled question, the stream has a reference to your object when you subscribe to it and should be freed explicitly even though the Stream may eventually clean it up on its own.

Upvotes: 5

Related Questions