← → or space · progress saves for Continue on the roadmap
Goal
Push events into a stream from imperative code with add, addError, and close.
Step 1 - Single-subscription controller
import 'dart:async';
Future<void> main() async {
final ctrl = StreamController<int>();
ctrl.add(1);
ctrl.add(2);
ctrl.close();
await for (final v in ctrl.stream) {
print(v);
}
}Step 2 - Broadcast for multiple listeners
import 'dart:async';
void main() {
final ctrl = StreamController<int>.broadcast();
ctrl.stream.listen(print);
ctrl.stream.listen((v) => print('again $v'));
ctrl.add(7);
ctrl.close();
}- Default controllers allow only one
listenunless you usebroadcast().
Step 3 - Lifecycle
- Call
close()when no more events will arrive so listeners can finish. - Prefer
StreamControllerfields on a class that exposesstreampublicly and keepsaddprivate if you need encapsulation.
Practice tasks
- Wrap a
Timer.periodicthatadds ticks into a controller; cancel the timer inonCancelif you useStreamControllerwith a listener API. - Compare memory: one listener vs two on a non-broadcast stream and note the runtime error.