Skip to content

Commit

Permalink
Sync updates to system clock
Browse files Browse the repository at this point in the history
Syncing with system clock looks nicer when the app is next to it.
  • Loading branch information
danielchalmers committed Jun 12, 2022
1 parent 993236b commit 036ca89
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Network Monitor/Monitors/BandwidthMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class BandwidthMonitor : Monitor

protected abstract long GetTotalBytes();

protected BandwidthMonitor() : base(updateInterval: TimeSpan.FromSeconds(1))
protected BandwidthMonitor() : base(interval: TimeSpan.FromSeconds(1))
{
}

Expand Down
2 changes: 1 addition & 1 deletion Network Monitor/Monitors/LatencyMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class LatencyMonitor : Monitor
private readonly string _host;
private readonly int _timeout;

public LatencyMonitor(string host, TimeSpan timeout) : base(updateInterval: timeout)
public LatencyMonitor(string host, TimeSpan timeout) : base(interval: timeout)
{
Name = "Latency";
Icon = '⟳';
Expand Down
22 changes: 15 additions & 7 deletions Network Monitor/Monitors/Monitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ namespace Network_Monitor.Monitors;

public abstract class Monitor : ObservableObject
{
private readonly DispatcherTimer _updateTimer;
private readonly SystemClockTimer _timer;
private string _displayValue = string.Empty.PadRight(4);

protected Monitor(TimeSpan updateInterval)
protected Monitor(TimeSpan interval)
{
if (updateInterval > TimeSpan.Zero)
var intervalSeconds = (int)interval.TotalSeconds;

if (intervalSeconds > 0)
{
_updateTimer = new(DispatcherPriority.Normal)
_timer = new();
_timer.SecondChanged += async (_, _) =>
{
Interval = updateInterval
if (string.IsNullOrWhiteSpace(DisplayValue) || DateTime.Now.Second % intervalSeconds == 0)
await UpdateAsync();
};
_updateTimer.Tick += async (_, _) => await UpdateAsync();
_updateTimer.Start();
_timer.Start();
}
}

Expand All @@ -38,6 +41,11 @@ protected Monitor(TimeSpan updateInterval)
/// </summary>
public Brush IconBrush { get; protected set; }

/// <summary>
/// Interval to update in seconds.
/// </summary>
public int IntervalSeconds { get; protected set; } = 5;

/// <summary>
/// User-friendly text to show in the UI.
/// </summary>
Expand Down
49 changes: 49 additions & 0 deletions Network Monitor/SystemClockTimer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading;

namespace Network_Monitor;

/// <summary>
/// A timer that is synced with the system clock.
/// </summary>
/// <remarks>
/// <see href="https://github.com/danielchalmers/DesktopClock" />
/// </remarks>
public sealed class SystemClockTimer : IDisposable
{
private readonly Timer _timer;

public SystemClockTimer()
{
_timer = new Timer(_ => OnTick());
}

/// <summary>
/// Occurs after the second of the system clock changes.
/// </summary>
public event EventHandler SecondChanged;

/// <summary>
/// Number of milliseconds until the next second on the system clock.
/// </summary>
private int MillisecondsUntilNextSecond => 1000 - DateTimeOffset.Now.Millisecond;

public void Dispose() => _timer.Dispose();

public void Start() => ScheduleTickForNextSecond();

public void Stop() => _timer.Change(Timeout.Infinite, Timeout.Infinite);

private void OnTick()
{
ScheduleTickForNextSecond();

SecondChanged?.Invoke(this, EventArgs.Empty);
}

/// <summary>
/// Starts the timer and schedules the tick for the next second on the system clock.
/// </summary>
private void ScheduleTickForNextSecond() =>
_timer.Change(MillisecondsUntilNextSecond, Timeout.Infinite);
}

0 comments on commit 036ca89

Please sign in to comment.