IVSoftware.Portable.WatchdogTimer
1.2.1
Prefix Reserved
See the version list below for details.
dotnet add package IVSoftware.Portable.WatchdogTimer --version 1.2.1
NuGet\Install-Package IVSoftware.Portable.WatchdogTimer -Version 1.2.1
<PackageReference Include="IVSoftware.Portable.WatchdogTimer" Version="1.2.1" />
paket add IVSoftware.Portable.WatchdogTimer --version 1.2.1
#r "nuget: IVSoftware.Portable.WatchdogTimer, 1.2.1"
// Install IVSoftware.Portable.WatchdogTimer as a Cake Addin #addin nuget:?package=IVSoftware.Portable.WatchdogTimer&version=1.2.1 // Install IVSoftware.Portable.WatchdogTimer as a Cake Tool #tool nuget:?package=IVSoftware.Portable.WatchdogTimer&version=1.2.1
Watchdog timer
What is it?
A timer that completes one time, after the TimeSpan in the Interval
property has elapsed since the most recent call to the StartOrRestart
method, regardless of the number of restarts. Invoking the Cancel
method negates any enqueued action or event in the queue.
Examples
Display an alert after user moves the mouse
Suppose we're interested in mouse move events, but obviously don't want to make a message each time one occurs.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
WatchdogTimer _wdtMouseMove = new WatchdogTimer
{
Interval = TimeSpan.FromSeconds(0.5)
};
DateTime _mouseStartTimeStamp = DateTime.MinValue;
protected override void OnMouseMove(MouseEventArgs e)
{
if(!_wdtMouseMove.Running)
{
_mouseStartTimeStamp = DateTime.Now;
}
_wdtMouseMove.StartOrRestart(() =>
{
BeginInvoke(() =>
MessageBox.Show(
$"Mouse down @ {
_mouseStartTimeStamp.ToString(@"hh\:mm\:ss tt")
}\nTime now is {
DateTime.Now.ToString(@"hh\:mm\:ss tt")
}."));
});
base.OnMouseMove(e);
}
}
Debouncing
An impatient user might tap multiple times. A watchdog timer can ensure that an action takes place the first time, and requires a cooling off interval before the same action can happen again.
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
BindingContext = this;
InitializeComponent();
}
private void OnCounterClicked(object sender, EventArgs e)
{
if (checkboxIsLockOutMechanismEnabled.IsChecked)
{
ExtendLockout();
}
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
WatchdogTimer _wdtOverlay = new WatchdogTimer { Interval = TimeSpan.FromSeconds(2) };
private void ExtendLockout()
{
_wdtOverlay.StartOrRestart(
initialAction: () => IsLockedOut = true,
completeAction: () => IsLockedOut = false);
}
public bool IsLockedOut
{
get => _isLockedOut;
set
{
if (!Equals(_isLockedOut, value))
{
_isLockedOut = value;
OnPropertyChanged();
}
}
}
bool _isLockedOut = false;
private void OnOverlayTapped(object sender, TappedEventArgs e)
{
ExtendLockout();
}
}
Methods
/// <summary>
/// Restart the watchdog timer.
/// </summary>
/// <remarks>
/// Core method that can take a parameterized action as well as a custom EventArgs object.
/// </remarks>
public void StartOrRestart(Action action, EventArgs e)
{
Running = true;
_wdtCount++;
var capturedCount = _wdtCount;
_isCancelled= false;
Task
.Delay(Interval)
.GetAwaiter()
.OnCompleted(() =>
{
// If the 'captured' localCount has not changed after awaiting the Interval,
// it indicates that no new 'bones' have been thrown during that interval.
if (capturedCount.Equals(_wdtCount) && !_isCancelled)
{
action?.Invoke();
Running = false;
RanToCompletion?.Invoke(this, e ?? EventArgs.Empty);
}
});
}
/// <summary>
/// Restart the watchdog timer.
/// </summary>
/// <remarks>
/// Subscribe to the RanToCompletion event to receive notification of completion.
/// On completion, fire an event with an empty EventArgs object.
/// </remarks>
public void StartOrRestart() => StartOrRestart(null, EventArgs.Empty);
/// <summary>
/// Restart the watchdog timer injecting a custom event to be fired on completion.
/// </summary>
/// <remarks>
/// Subscribe to the RanToCompletion event to receive notification of completion.
/// On completion, fire an event using a custom parameterized EventArgs object.
/// </remarks>
public void StartOrRestart(EventArgs e) => StartOrRestart(null, e);
/// <summary>
/// Restart the watchdog timer with action to invoke on completion.
/// </summary>
/// <remarks>
/// Subscribe to the RanToCompletion event to receive notification of completion.
/// On completion, invoke a parameterized action.
/// </remarks>
public void StartOrRestart(Action action) => StartOrRestart(action, EventArgs.Empty);
/// <summary>
/// Restart the watchdog timer with actions to invoke on initialization and completion.
/// </summary>
/// <remarks>
/// Invoke an initial parameterized action if not already running.
/// Subscribe to the RanToCompletion event to receive notification of completion.
/// On completion, invoke a parameterized action.
/// </remarks>
public void StartOrRestart(Action initialAction, Action completeAction);
public void Cancel() => _isCancelled = true;
Properties
public TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(1);
public bool Running { get; private set; }
Event
public event EventHandler RanToCompletion;
StackOverflow
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.3.0-prerelease | 93 | 10/20/2024 |
1.2.1 | 292 | 11/7/2023 |