Why TcpClient.Connect is not throwing exception in async method even if it is running synchroneously

  1. Why this code is not throwing System.Net.Sockets.SocketException even if no await is specified? (no server is listening at specified port )
  2. Why Thread.Sleep(4000); is not executed?

    public class AsyncTcpClientDemos
    {
       private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();
    
       public async Task ConnectTcpClientNoException()
       {
           Logger.Debug("ConnectTcpClientNoException() - start");
           var tcp = new TcpClient();
           tcp.Connect("127.0.0.1", 9045);
           Thread.Sleep(4000);
       }
    }
    

Method is called from within NUnit test:

[Test]
public void AsyncTcpClientNoExceptionTest()
{
    var asyncAwait = new AsyncTcpClientDemos();

    // TODO: find out why this is not throwing exception
    asyncAwait.ConnectTcpClientNoException();            
}
Jon Skeet
people
quotationmark

An async method never throws an exception directly. Instead, if an exception is raised within the body of the method, the task returned by the async method becomes faulted.

The sleep isn't executed because the exception does prevent the rest of the method from executing - it's just that the exception is propagated via the Task instead of straight up the stack.

If you really want the first part of a method to throw an exception, you can split it into two. For example:

public Task FooAsync(int x, int y)
{
    if (x < y)
    {
        // This will be thrown straight to the caller, in the
        // normal way
        throw new ArgumentException("...");
    }
    return FooAsyncImpl(x, y);
}

private async Task FooAsyncImpl(int x, int y)
{
    // Any exceptions thrown here will be propagated via the task
}

people

See more on this question at Stackoverflow