I have recently discovered by accident that I don't need to await a Task to get the exceptions that Task throws for program control logic.
Pre discovery of this feature, my code would look like this:
using (TcpClient client = new TcpClient())
{
try
{
var ca = client.ConnectAsync("192.168.1.88", 9999);
await await Task.WhenAny(ca, Task.Delay(5000));
if (ca.IsCompleted)
Console.WriteLine("Connected");
else
Console.WriteLine("Connection failed due to timeout");
}
catch
{
Console.WriteLine("Connection failed.");
}
}
Post discovery my code looks like this, (which personally I find more readable)
using (TcpClient client = new TcpClient())
{
var ca = client.ConnectAsync("192.168.1.88", 9999);
await Task.WhenAny(ca, Task.Delay(5000));
if (ca.IsFaulted || !ca.IsCompleted)
Console.WriteLine("Connection failed due to timeout or exception");
else
Console.WriteLine("Connected");
}
Is there anything technically wrong with intentionally leaving the unobserved exceptions to be ignored by the TaskScheduler? E.g., will they back up and cause other problems in the async/await framework?
The behavior is further described in this question.
WhenAnyinstead of going directly to checkingca. Depending on the environment and the way the tasks were started, theif (ca.IsFaulted || !ca.IsCompleted)may be a race condition provided that it was notcathat was returned fromWhenAny.catchin place, it will only catch exception from the first task. Exceptions from the other tasks will remain unobserved, and if it's okay to leave them that way, then it's not clear why the exception from the winning task would be any different.Task.Delay()finishes first.