Last active
October 11, 2018 21:04
-
-
Save danielmarbach/4485bd542c2a9db6784f4b0ff7fbbb98 to your computer and use it in GitHub Desktop.
This file contains 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
public static class TimeboxExtensions | |
{ | |
public static async Task Timebox(this IEnumerable<Task> tasks, TimeSpan timeoutAfter, string messageWhenTimeboxReached) | |
{ | |
using (var tokenSource = new CancellationTokenSource()) | |
{ | |
var delayTask = Task.Delay(Debugger.IsAttached ? TimeSpan.MaxValue : timeoutAfter, tokenSource.Token); | |
var allTasks = Task.WhenAll(tasks); | |
var returnedTask = await Task.WhenAny(delayTask, allTasks).ConfigureAwait(false); | |
tokenSource.Cancel(); | |
if (returnedTask == delayTask) | |
{ | |
throw new TimeoutException(messageWhenTimeboxReached); | |
} | |
await allTasks.ConfigureAwait(false); | |
} | |
} | |
} |
This file contains 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
[TestFixture] | |
public class TimeboxExtensionsTests | |
{ | |
[Test] | |
public void ThrowsTimeoutException() | |
{ | |
var allTasks = new[] { Task.Delay(20), Task.Delay(50)}; | |
var exception = Assert.ThrowsAsync<TimeoutException>(async () => { await allTasks.Timebox(TimeSpan.FromMilliseconds(20), "Problem due to timeout"); }); | |
Assert.AreEqual("Problem due to timeout", exception.Message); | |
} | |
[Test] | |
public void DoesNotThrowWhenCompleted() | |
{ | |
var allTasks = new[] {Task.Delay(20), Task.Delay(50)}; | |
Assert.DoesNotThrowAsync(async () => { await allTasks.Timebox(TimeSpan.FromMilliseconds(100), "Problem"); }); | |
} | |
[Test] | |
public void ThrowsExceptionOfTasks() | |
{ | |
var invalidOperationException = new InvalidOperationException(); | |
var allTasks = new[] { Task.Delay(20), Task.Delay(50), Task.Delay(50).ContinueWith(t => throw invalidOperationException) }; | |
var exception = Assert.ThrowsAsync<InvalidOperationException>(async () => { await allTasks.Timebox(TimeSpan.FromMilliseconds(100), "Problem"); }); | |
Assert.AreSame(invalidOperationException, exception); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment