Please, observe the following trivial code:
class Program
{
static void Main()
{
var sw = new Stopwatch();
sw.Start();
try
{
Task.WhenAny(RunAsync()).GetAwaiter().GetResult();
}
catch (TimeoutException)
{
Console.WriteLine("Timed out");
}
Console.WriteLine("Elapsed: " + sw.Elapsed);
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
private static async Task RunAsync()
{
await Observable.StartAsync(async ct =>
{
for (int i = 0; i < 10; ++i)
{
await Task.Delay(500, ct);
Console.WriteLine("Inside " + i);
}
return Unit.Default;
}).Timeout(TimeSpan.FromMilliseconds(1000));
}
}
Running it outputs:
Inside 0
Inside 1
Elapsed: 00:00:01.1723818
Press Enter to exit
Note, no Timed out message.
Now, if I replace Task.WhenAny
with Task.WhenAll
here is what I get:
Inside 0
Inside 1
Timed out
Elapsed: 00:00:01.1362188
Press Enter to exit
Note the presence of the Timed out message this time.
And, if I remove the Task.WhenAll
wrapper at all and call RunAsync
directly:
Inside 0
Inside 1
Timed out
Elapsed: 00:00:01.1267617
Press Enter to exit
The Timed out message is there, as expected.
So what is the deal with Task.WhenAny
? It obviously interrupts the asynchronous method, but where is the TimeoutException
?