kageeker
kageeker

Reputation: 527

Calling Drain() on a Stream never returns and the stream never closes

I am using dart Streams in my Flutter app following the BLOC pattern , so logically whenever i am done with a Bloc , i need to dispose all the streams i have inside it.

So on my dispose method provided by the stateful widget i am calling the drain method like this :

dispose() async {
    print('Started Dispose');

    await _mainStream.drain();

    print('_mainStream Drained');
  }

So what happens is that i see the first print but never the second one which means my stream is not drained and if i listen to the stream and print something whenever i get a new event, i still see that message in the Debug Console even tho my Bloc is Disposed from the widget tree.

So basically my stream is still there somewhere. How can i solve this issue because its driving me crazy.

Upvotes: 3

Views: 2535

Answers (1)

Renato
Renato

Reputation: 13690

To stop listening on a stream, you cancel your subscription, not call drain. Streams can be "forever", in the sense that they will keep emitting events until they are closed. For this reason, trying to drain such streams is dangerous as it will never complete.

Here's a simple example of how you can cancel your subscription:

final foreverStream = Stream.periodic(Duration(milliseconds: 10), (i) => i);

main() async {
  final subscription = foreverStream.listen((event) => print("EVENT: $event"));  

  await Future.delayed(Duration(milliseconds: 100));

  await subscription.cancel();
  print("Done");
}

If you'd failed to cancel the subscription, it would just keep printing forever or until you killed the process.

Upvotes: 4

Related Questions