Exemple #1
0
        public static Stream <T> periodic(TimeSpan period,
                                          Func <int, T> computation = null)
        {
            Timer timer                     = default;
            int   computationCount          = 0;
            StreamController <T> controller = null;
            // Counts the time that the Stream was running (and not paused).
            Stopwatch watch = new Stopwatch();

            Action sendEvent = () => {
                watch.reset();
                T data = default;
                if (computation != null)
                {
                    try {
                        data = computation(computationCount++);
                    }
                    catch (Exception e) {
                        controller.addError(e, e.StackTrace);
                        return;
                    }
                }

                controller.add(data);
            };

            Action startPeriodicTimer = () => {
                D.assert(timer == null);
                timer = Timer.periodic(period, (object timer1) => {
                    sendEvent();
                    return(null);
                });
            };

            // the original code new an abstract class
            controller = StreamController <T> .create(
                sync : true,
                onListen : () => {
                watch.start();
                startPeriodicTimer();
            },
                onPause : () => {
                timer.cancel();
                timer = null;
                watch.stop();
            },
                onResume : () => {
                D.assert(timer == null);
                TimeSpan elapsed = watch.elapsed;
                watch.start();
                timer = Timer.create(period - elapsed, () => {
                    timer = null;
                    startPeriodicTimer();
                    sendEvent();
                });
            },
                onCancel : () => {
                if (timer != null)
                {
                    timer.cancel();
                }
                timer = null;
                return(Future._nullFuture);
            });

            return(controller.stream);
        }