Home > OS >  Exit an infinite stream
Exit an infinite stream

Time:07-27

I've written this piece of code in order to scan Bluetooth devices in my Flutter app with the help of flutter_blue package.

Stream<List<ScanResult>> scannedDevices(int durationSeconds) async* {
  Stream<List<ScanResult>> stream = _flutterBlue.scanResults;
  List<ScanResult> payload = List<ScanResult>.empty(growable: true);

  _flutterBlue.startScan(timeout: Duration(seconds: durationSeconds));

  await for (List<ScanResult> results in stream) {
    payload.clear();
    for (ScanResult result in results) {
      payload.add(result);
    }
    yield payload;
}

The problem is that scanResults Stream is infitnite (see here) and because of that the await for loop runs foreverer, leaving my scannedDevices Stream running forever too.

Is there a way to break the await for loop after scanDuration has passed? Thanks

CodePudding user response:

Simply add an timeout to the stream that you are listening.

Another option is to use the StreamTransformer instead of what you did with await for.

Stream<List<ScanResult>> scannedDevices(int durationSeconds) async* {
  Stream<List<ScanResult>> stream = _flutterBlue.scanResults.timeout(Duration(seconds: durationSeconds));
  List<ScanResult> payload = List<ScanResult>.empty(growable: true);

  _flutterBlue.startScan(timeout: Duration(seconds: durationSeconds));

  await for (List<ScanResult> results in stream) {
      payload.clear();
      for (ScanResult result in results) {
        payload.add(result);
      }
      yield payload;
  }
}

CodePudding user response:

Yes, you can simply return null for breaking loop

 Stream<List<ScanResult>> scannedDevices(int durationSeconds) 
  async* {
    Stream<List<ScanResult>> stream = _flutterBlue.scanResults;
     List<ScanResult> payload = List<ScanResult>.empty(growable: 
       true);

     _flutterBlue.startScan(timeout: Duration(seconds: 
 durationSeconds));

 await for (List<ScanResult> results in stream) {
   payload.clear();
   for (ScanResult result in results) {
  payload.add(result);
 }
return payload;
}
  • Related