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(); }
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); }
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}"); } } }