Пример #1
0
        public void ResetDue <T>(T item)
            where T : ISensorScanRateItem
        {
            if (!LastMeasurement.ContainsKey(item))
            {
                throw new InvalidOperationException("Sensor configuration item has not been registered earlier");
            }

            LastMeasurement[item].Restart();
        }
Пример #2
0
        public bool IsDue <T>(T item)
            where T : ISensorScanRateItem
        {
            if (!LastMeasurement.ContainsKey(item))
            {
                throw new InvalidOperationException("Sensor configuration item has not been registered earlier");
            }

            var stopwatch = LastMeasurement[item];

            return(stopwatch.Elapsed >= item.ScanRate);
        }
Пример #3
0
        private async Task Main(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    if (IsConnected)
                    {
                        // collect due items
                        var dueItems = LastMeasurement
                                       .Where(t => IsDue(t.Key))
                                       .Select(t => t.Key)
                                       .ToList();
                        if (dueItems.Any())
                        {
                            await OnIsDue(dueItems, cancellationToken);
                        }
                        else
                        {
                            // no items due
                        }
                    }
                    else
                    {
                        // do not request measurements while disconnected
                        // we have to delay in this situation at least for some
                        // time to avoid hot looping
                        Console.WriteLine($"Not connected, delaying new measurements for one second ..");
                        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                    }

                    // delay and wait for next cycle
                    var nextDueTimes = LastMeasurement
                                       .Select(t => t.Key.ScanRate - t.Value.Elapsed)
                                       .Distinct()
                                       .OrderBy(t => t)
                                       .ToList();
                    if (nextDueTimes.Count > 0)
                    {
                        var minDueTime = nextDueTimes.First();

                        // this delay is a smart guess observing that a Task.Delay() won't
                        // be accurate enough to accomodate a delay shorter than this interval.
                        // better avoid unnecessary delays if the smallest delay is shorter than this
                        // upon reaching this interval it is better to skip the delay and straight
                        // check if any item is due
                        var smallestPossibleDelay = TimeSpan.Zero;
                        if (minDueTime < smallestPossibleDelay)
                        {
                            // another item is already due, skip delay
                        }
                        else
                        {
                            await Task.Delay(minDueTime, cancellationToken);
                        }
                    }
                    else
                    {
                        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                    }
                }
                catch (TaskCanceledException)
                {
                    // ignore
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Measurement request generator caught exception and resumes operation: {ex}");
                }
            }
        }