I'm trying to write a helper method which allows me to pass in an arbitrary task and a timeout. If the task completes before the timeout, a success delegate is called, otherwise an error delegate is called. The method looks like this:
public static async Task AwaitWithTimeout(Task task, int timeout, Action success, Action error) { if (await Task.WhenAny(task, Task.Delay(timeout)) == task) { if (success != null) { success(); } } else { if (error != null) { error(); } } } Now this seems to work most of the time, but i wanted to write some tests as well to make sure. This test, to my surprise fails, and calls the error delegate instead of the success:
var taskToAwait = Task.Delay(1); var successCalled = false; await TaskHelper.AwaitWithTimeout(taskToAwait, 10, () => successCalled = true, null); Assert.IsTrue(successCalled); This test, however, is green:
var taskToAwait = Task.Run(async () => { await Task.Delay(1); }); var successCalled = false; await TaskHelper.AwaitWithTimeout(taskToAwait, 10, () => successCalled = true, null); Assert.IsTrue(successCalled); How do i make both tests green? Is my usage of Task.WhenAny incorrect?
Delay(1)is very short (especially if you are debugging) - starting it on separate thread make it sufficiently long for your test to pass most of the time. Try to use longer delay or better yet task that allows to manually complete it synchronously in test.