为什么TcpClient.Connect不会在异步方法中抛出异常,即使它是同步运行的

And*_* F. 1 .net c# multithreading asynchronous async-await

  1. 为什么即使没有指定await,此代码也不会抛出System.Net.Sockets.SocketException?(没有服务器正在侦听指定的端口)
  2. 为什么选择Thread.Sleep(4000); 没有执行?

    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);
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)

从NUnit测试中调用方法:

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

    // TODO: find out why this is not throwing exception
    asyncAwait.ConnectTcpClientNoException();            
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

一种async方法从不直接抛出异常.相反,如果在方法体内引发异常,则异步方法返回的任务将出现故障.

不执行休眠,因为异常确实阻止了方法的其余部分执行 - 只是异常通过Task堆栈而不是直接向上传播.

如果您确实希望方法的第一部分抛出异常,则可以将其拆分为两个.例如:

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
}
Run Code Online (Sandbox Code Playgroud)