Last active
April 6, 2018 08:26
-
-
Save jrgcubano/eee36ee3783c3fb38277931c30b20c2d to your computer and use it in GitHub Desktop.
Task HeartBeats Extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static async Task PerformHeartbeat(CancellationToken cancellationToken) { | |
Console.WriteLine("Starting heartbeat {0}", ++_heartbeatCount); | |
await Task.Delay(1000, cancellationToken); | |
Console.WriteLine("Finishing heartbeat {0}", _heartbeatCount); | |
} | |
The PerformHeartbeat could be replaced with an async call like RenewLockAsync so that you wouldn't | |
have to waste thread time using a blocking call like RenewLock that the Action approach would require. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Via: https://stackoverflow.com/questions/17115385/creating-a-task-with-a-heartbeat | |
/// <summary> | |
/// Awaits a fresh Task created by the <paramref name="heartbeatTaskFactory"/> once every <paramref name="heartbeatInterval"/> while <paramref name="primaryTask"/> is running. | |
/// </summary> | |
public static async Task WithHeartbeat(this Task primaryTask, TimeSpan heartbeatInterval, Func<CancellationToken, Task> heartbeatTaskFactory, CancellationToken cancellationToken) { | |
if (cancellationToken.IsCancellationRequested) { | |
return; | |
} | |
var stopHeartbeatSource = new CancellationTokenSource(); | |
cancellationToken.Register(stopHeartbeatSource.Cancel); | |
await Task.WhenAll(primaryTask, PerformHeartbeats(heartbeatInterval, heartbeatTaskFactory, stopHeartbeatSource.Token)); | |
if (!stopHeartbeatSource.IsCancellationRequested) { | |
stopHeartbeatSource.Cancel(); | |
} | |
} | |
public static Task WithHeartbeat(this Task primaryTask, TimeSpan heartbeatInterval, Func<CancellationToken, Task> heartbeatTaskFactory) { | |
return WithHeartbeat(primaryTask, heartbeatInterval, heartbeatTaskFactory, CancellationToken.None); | |
} | |
private static async Task PerformHeartbeats(TimeSpan interval, Func<CancellationToken, Task> heartbeatTaskFactory, CancellationToken cancellationToken) { | |
while (!cancellationToken.IsCancellationRequested) { | |
try { | |
await Task.Delay(interval, cancellationToken); | |
if (!cancellationToken.IsCancellationRequested) { | |
await heartbeatTaskFactory(cancellationToken); | |
} | |
} | |
catch (TaskCanceledException tce) { | |
if (tce.CancellationToken == cancellationToken) { | |
// Totally expected | |
break; | |
} | |
throw; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment