prega, osservare il seguente codice banale:Perché il Task.WhenAny non lancia un TimeoutException previsto?
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));
}
}
esecuzione emette:
Inside 0
Inside 1
Elapsed: 00:00:01.1723818
Press Enter to exit
nota, non scaduta messaggio.
Ora, se sostituisco Task.WhenAny
con Task.WhenAll
qui è quello che ottengo:
Inside 0
Inside 1
Timed out
Elapsed: 00:00:01.1362188
Press Enter to exit
nota la presenza del scaduta messaggio questa volta.
E, se mi tolgo la Task.WhenAll
involucro a tutti e chiamare direttamente RunAsync
:
Inside 0
Inside 1
Timed out
Elapsed: 00:00:01.1267617
Press Enter to exit
Il Timeout messaggio è lì, come previsto.
Quindi, qual è l'accordo con Task.WhenAny
? Ovviamente interrompe il metodo asincrono, ma dov'è lo TimeoutException
?
Perché stai usando '.Task.GetAwaiter() .GetResult() ', in primo luogo è equivoco a' Task.Result' e in secondo luogo si rischia di essere mangiato da un grue. – Aron
@Aron Non è equivalente. Genera l'eccezione reale. Ma sì, sta ancora bloccando e potrebbe portare a deadlock. – i3arnon
[Task.getAwaiter()] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.getawaiter (v = vs.110) .aspx): 'Questo metodo è destinato per l'uso del compilatore piuttosto che per l'uso nel codice dell'applicazione. – sstan