简体   繁体   中英

How to allow only single executed task using streams or buffering stream event while executing long operation

I have some process which can be called periodically and forcibly. The process can take some time. I need to disallow to start next automatic task until forcible task is still executing, or I need to disallow the forcible task until automatic task is still executing (ie only one active task is allowed). Yes, I understand that I can use some _isBusy flag to define if task is still executing and skip adding to sink. But maybe there is a more elegant solution using streams (rxdart)? Moreover I would like if events not be missed but buffered so when the active task is completed, the next event is taken from _controller.stream .

class Processor {
  bool _isBusy;
  final _controller = StreamController<int>.broadcast();

  Processor() {
    _controller.stream.listen((_) async {
      if (!_isBusy) {
        await _execTask(); // execute long task
      }
    });
  }

  void startPeriodicTask() {
    Stream.periodic(duration: Duration(seconds: 15)).listen((_) {
      _controller.sink.add(1);
    })
  }

  void execTask() {
    _controller.sink.add(1);
  }

  void _execTask() async {
    try {
      _isBusy = true;
      // doing some staff
    } finally {
      _isBusy = false;
    }        
  }
}

I looked at rxdart reference , but I can't find the elegant method.

If I was to say it, you can where .

_controller.stream.where((_) => !_isBusy).listen((_) async {
    await _execTask();
});

After some experience I got I found out that each event in stream is processed one by one. So when one event is still processing the second one is waiting its turn in stream and more over sent events are not missing !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM