最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - Can’t cancel a stream subscription - Stack Overflow

programmeradmin0浏览0评论

I have this code:

import 'dart:async';
import 'dart:math';

class TestService {
  Random random = Random();
  StreamController<double> streamController = StreamController<double>();
  StreamController<double> streamController2 = StreamController<double>();
  late StreamSubscription<double> streamSubscription;
  late StreamSubscription<double> streamSubscription2;

  void startSending() {
        streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()).take(5));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });
  }
  void stopSending() {
    streamSubscription.cancel();
    streamController.close();
  }

  void startAndStop(){
    streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });

    Future.delayed(Duration(seconds: 10),() {
      streamSubscription.cancel();
      streamController.close();
    },);
  }
  void dispose() {
    streamController.close();
    streamController2.close();
  }
}

And I want to know why can't I cancel the streamSubscription from the stopSending(). Also, I don't know why but startAndStop() works perfect and somehow when I use stopSending() I get this error:

======== Exception caught by gesture ===============================================================
The following LateError was thrown while handling a gesture:
LateInitializationError: Field 'streamSubscription' has not been initialized.

When the exception was thrown, this was the stack: 
#0      TestService.streamSubscription (package:foolad/customeWidgets/tempDevice.dart)
#1      TestService.stopSending (package:foolad/customeWidgets/tempDevice.dart:18:5)
#2      SelectSourceTypeController.testDeviceListenClose (package:foolad/app/modules/select_source_type/controllers/select_source_type_controller.dart:36:19)
#3      SelectSourceTypeView.build.<anonymous closure> (package:foolad/app/modules/select_source_type/views/select_source_type_view.dart:29:30)
#4      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1176:21)
#5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:351:24)
#6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:656:11)
#7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:313:5)
#8      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:246:7)
#9      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:703:9)
#10     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#12     _LinkedHashMapMixin.forEach (dart:_compact_hash:726:13)
#13     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#14     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#15     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:502:19)
#16     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:482:22)
#17     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:457:11)
#18     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:427:7)
#19     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:390:5)
#20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:337:7)
#21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:306:9)
#22     _invoke1 (dart:ui/hooks.dart:328:13)
#23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:450:7)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#e3ff5
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(295.0, 70.0)
  finalLocalPosition: Offset(295.0, 23.0)
  button: 1
  sent tap down
====================================================================================================

Can someone explain this to me?

I used:

void startAndStop(){
    streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });

    Future.delayed(Duration(seconds: 10),() {
      streamSubscription.cancel();
      streamController.close();
    },);
  }

And I could use subscription in the same function but not in another one.

I have this code:

import 'dart:async';
import 'dart:math';

class TestService {
  Random random = Random();
  StreamController<double> streamController = StreamController<double>();
  StreamController<double> streamController2 = StreamController<double>();
  late StreamSubscription<double> streamSubscription;
  late StreamSubscription<double> streamSubscription2;

  void startSending() {
        streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()).take(5));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });
  }
  void stopSending() {
    streamSubscription.cancel();
    streamController.close();
  }

  void startAndStop(){
    streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });

    Future.delayed(Duration(seconds: 10),() {
      streamSubscription.cancel();
      streamController.close();
    },);
  }
  void dispose() {
    streamController.close();
    streamController2.close();
  }
}

And I want to know why can't I cancel the streamSubscription from the stopSending(). Also, I don't know why but startAndStop() works perfect and somehow when I use stopSending() I get this error:

======== Exception caught by gesture ===============================================================
The following LateError was thrown while handling a gesture:
LateInitializationError: Field 'streamSubscription' has not been initialized.

When the exception was thrown, this was the stack: 
#0      TestService.streamSubscription (package:foolad/customeWidgets/tempDevice.dart)
#1      TestService.stopSending (package:foolad/customeWidgets/tempDevice.dart:18:5)
#2      SelectSourceTypeController.testDeviceListenClose (package:foolad/app/modules/select_source_type/controllers/select_source_type_controller.dart:36:19)
#3      SelectSourceTypeView.build.<anonymous closure> (package:foolad/app/modules/select_source_type/views/select_source_type_view.dart:29:30)
#4      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1176:21)
#5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:351:24)
#6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:656:11)
#7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:313:5)
#8      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:246:7)
#9      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:703:9)
#10     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#12     _LinkedHashMapMixin.forEach (dart:_compact_hash:726:13)
#13     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#14     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#15     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:502:19)
#16     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:482:22)
#17     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:457:11)
#18     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:427:7)
#19     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:390:5)
#20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:337:7)
#21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:306:9)
#22     _invoke1 (dart:ui/hooks.dart:328:13)
#23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:450:7)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#e3ff5
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(295.0, 70.0)
  finalLocalPosition: Offset(295.0, 23.0)
  button: 1
  sent tap down
====================================================================================================

Can someone explain this to me?

I used:

void startAndStop(){
    streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });

    Future.delayed(Duration(seconds: 10),() {
      streamSubscription.cancel();
      streamController.close();
    },);
  }

And I could use subscription in the same function but not in another one.

Share edited Mar 4 at 11:54 Biffen 6,3496 gold badges31 silver badges37 bronze badges asked Mar 4 at 11:36 RJ84RJ84 32 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You can't stop before you started it because streamSubscription hasn't been initiliazed then. The best way to handle it is to not use late variables for this but nullable variables and then use the null-safe operator "?". So like this:

import 'dart:async';
import 'dart:math';

class TestService {
  Random random = Random();
  StreamController<double> streamController = StreamController<double>();
  StreamController<double> streamController2 = StreamController<double>();
  StreamSubscription<double>? streamSubscription;
  StreamSubscription<double>? streamSubscription2;

  void startSending() {
        streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()).take(5));
    streamSubscription?.cancel(); //might be smart to add this line here in case there already was a subsciption, so it gets canceled
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });
  }
  void stopSending() {
    streamSubscription?.cancel(); //added ? here
    streamController.close();
  }

  void startAndStop(){
    streamController.addStream(Stream.periodic(Duration(seconds: 1), (count) => count.toDouble()));
    streamSubscription = streamController.stream.listen((event) {
      print('event 2:$event');
    });

    Future.delayed(Duration(seconds: 10),() {
      streamSubscription?.cancel(); //added ? here
      streamController.close();
    },);
  }
  void dispose() {
    streamController.close();
    streamController2.close();
  }
}
发布评论

评论列表(0)

  1. 暂无评论